void CPPSourceCodeDocument::updateContent( )
{
    // Gather info on the various fields and parent objects of this class...
    //UMLClassifier * c = getParentClassifier();
    CodeGenPolicyExt *pe = UMLApp::app()->policyExt();
    CPPCodeGenerationPolicy * policy = dynamic_cast<CPPCodeGenerationPolicy*>(pe);
    QString endLine = UMLApp::app()->commonPolicy()->getNewLineEndingChars();

    // first, set the global flag on whether or not to show classfield info
    const CodeClassFieldList * cfList = getCodeClassFieldList();
    CodeClassFieldList::const_iterator it = cfList->begin();
    CodeClassFieldList::const_iterator end = cfList->end();
    for( ; it != end; ++it )
        (*it)->setWriteOutMethods(policy->getAutoGenerateAccessors());

    // attribute-based ClassFields
    // we do it this way to have the static fields sorted out from regular ones
    CodeClassFieldList staticAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true);
    CodeClassFieldList attribClassFields = getSpecificClassFields (CodeClassField::Attribute, false);
    // association-based ClassFields
    // don't care if they are static or not..all are lumped together
    CodeClassFieldList plainAssocClassFields = getSpecificClassFields ( CodeClassField::PlainAssociation );
    CodeClassFieldList aggregationClassFields = getSpecificClassFields ( CodeClassField::Aggregation );
    CodeClassFieldList compositionClassFields = getSpecificClassFields ( CodeClassField::Composition );

    // START GENERATING CODE/TEXT BLOCKS and COMMENTS FOR THE DOCUMENT

    // INCLUDE CODEBLOCK
    QString includeStatement;
    // Include own header file
    QString myOwnName( getParentClassifier()->name() );
    includeStatement.append("#include \""+CodeGenerator::cleanName(myOwnName.toLower())+".h\""+endLine);
    CodeBlockWithComments * iblock = addOrUpdateTaggedCodeBlockWithComments("includes", includeStatement, QString(), 0, false);
    iblock->setWriteOutText(true);

    // After the includes we have just 2 big blocks basically, the "constructor" block and the
    // block for the rest of our methods (operations + accessors)

    m_constructorBlock = getHierarchicalCodeBlock("constructionMethodsBlock", "Constructors/Destructors", 0);
    m_methodsBlock = getHierarchicalCodeBlock("otherMethodsBlock", "Methods", 0);

    // add accessors to the methods block
    m_methodsBlock->addCodeClassFieldMethods(staticAttribClassFields);
    m_methodsBlock->addCodeClassFieldMethods(attribClassFields);
    m_methodsBlock->addCodeClassFieldMethods(plainAssocClassFields);
    m_methodsBlock->addCodeClassFieldMethods(aggregationClassFields);
    m_methodsBlock->addCodeClassFieldMethods(compositionClassFields);

    // constructors and other operations are handled by the "addCodeOperation" method above.
}
// This method will cause the class to rebuild its text representation.
// based on the parent classifier object.
// For any situation in which this is called, we are either building the code
// document up, or replacing/regenerating the existing auto-generated parts. As
// such, we will want to insert everything we resonablely will want
// during creation. We can set various parts of the document (esp. the
// comments) to appear or not, as needed.
void RubyClassifierCodeDocument::updateContent()
{
    // Gather info on the various fields and parent objects of this class...
    UMLClassifier * c = getParentClassifier();
    RubyCodeGenerator * gen = dynamic_cast<RubyCodeGenerator*>(UMLApp::app()->generator());

    // first, set the global flag on whether or not to show classfield info
    // This depends on whether or not we have attribute/association classes
    const CodeClassFieldList * cfList = getCodeClassFieldList();
    CodeClassFieldList::const_iterator it = cfList->begin();
    CodeClassFieldList::const_iterator end = cfList->end();
    for (; it != end; ++it) {
        CodeClassField * field = *it;
        if (field->parentIsAttribute())
            field->setWriteOutMethods(gen->getAutoGenerateAttribAccessors());
        else
            field->setWriteOutMethods(gen->getAutoGenerateAssocAccessors());
    }
    // attribute-based ClassFields
    // we do it this way to have the static fields sorted out from regular ones
    CodeClassFieldList staticPublicAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true, Uml::Visibility::Public);
    CodeClassFieldList publicAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, false, Uml::Visibility::Public);
    CodeClassFieldList staticProtectedAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true, Uml::Visibility::Protected);
    CodeClassFieldList protectedAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, false, Uml::Visibility::Protected);
    CodeClassFieldList staticPrivateAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true, Uml::Visibility::Private);
    CodeClassFieldList privateAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, false, Uml::Visibility::Private);

    // association-based ClassFields
    // don't care if they are static or not..all are lumped together
    CodeClassFieldList publicPlainAssocClassFields = getSpecificClassFields (CodeClassField::PlainAssociation, Uml::Visibility::Public);
    CodeClassFieldList publicAggregationClassFields = getSpecificClassFields (CodeClassField::Aggregation, Uml::Visibility::Public);
    CodeClassFieldList publicCompositionClassFields = getSpecificClassFields (CodeClassField::Composition, Uml::Visibility::Public);

    CodeClassFieldList protPlainAssocClassFields = getSpecificClassFields (CodeClassField::PlainAssociation, Uml::Visibility::Protected);
    CodeClassFieldList protAggregationClassFields = getSpecificClassFields (CodeClassField::Aggregation, Uml::Visibility::Protected);
    CodeClassFieldList protCompositionClassFields = getSpecificClassFields (CodeClassField::Composition, Uml::Visibility::Protected);

    CodeClassFieldList privPlainAssocClassFields = getSpecificClassFields (CodeClassField::PlainAssociation, Uml::Visibility::Private);
    CodeClassFieldList privAggregationClassFields = getSpecificClassFields (CodeClassField::Aggregation, Uml::Visibility::Private);
    CodeClassFieldList privCompositionClassFields = getSpecificClassFields (CodeClassField::Composition, Uml::Visibility::Private);

    bool isInterface = parentIsInterface();
    bool hasOperationMethods = false;
    Q_ASSERT(c != NULL);
    if (c) {
        UMLOperationList list = c->getOpList();
        hasOperationMethods = ! list.isEmpty();
    }
    CodeGenerationPolicy *pol = UMLApp::app()->commonPolicy();
    QString endLine = pol->getNewLineEndingChars(); // a shortcut..so we don't have to call this all the time

    //
    // START GENERATING CODE/TEXT BLOCKS and COMMENTS FOR THE DOCUMENT
    //


    // CLASS DECLARATION BLOCK
    //

    // get the declaration block. If it is not already present, add it too
    RubyClassDeclarationBlock * myClassDeclCodeBlock = getClassDecl();
    addTextBlock(myClassDeclCodeBlock); // note: wont add if already present

    // declare public, protected and private methods, attributes (fields).
    // set the start text ONLY if this is the first time we created the objects.
    bool createdPublicBlock = publicBlock == 0 ? true : false;
    publicBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock(QLatin1String("publicBlock"), QLatin1String("Public Items"), 0);
    if (createdPublicBlock)
        publicBlock->setStartText(QLatin1String("public"));

    bool createdProtBlock = protectedBlock == 0 ? true : false;
    protectedBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock(QLatin1String("protectedBlock"), QLatin1String("Protected Items"), 0);
    if (createdProtBlock)
        protectedBlock->setStartText(QLatin1String("protected"));

    bool createdPrivBlock = privateBlock == 0 ? true : false;
    privateBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock(QLatin1String("privateBlock"), QLatin1String("Private Items"), 0);
    if (createdPrivBlock)
        privateBlock->setStartText(QLatin1String("private"));

    // NOW create document in sections..
    // now we want to populate the body of our class
    // our layout is the following general groupings of code blocks:

    // start ruby classifier document

    // header comment

     // class declaration

    //   section:

    //   section:
    //   - methods section comment

    //     sub-section: constructor ops
    //     - constructor method section comment
    //     - constructor methods (0+ codeblocks)

    //     sub-section: accessors
    //     - accessor method section comment
    //     - static accessor methods (0+ codeblocks)
    //     - non-static accessor methods (0+ codeblocks)

    //     sub-section: non-constructor ops
    //     - operation method section comment
    //     - operations (0+ codeblocks)

    // end class declaration

    // end ruby classifier document


    // Q: Why use the more complicated scheme of arranging code blocks within codeblocks?
    // A: This will allow us later to preserve the format of our document so that if
    //    codeblocks are added, they may be easily added in the correct place, rather than at
    //    the end of the document, or by using a difficult algorithm to find the location of
    //    the last appropriate code block sibling (which may not exist.. for example user adds
    //    a constructor operation, but there currently are no constructor code blocks
    //    within the document).


    //
    // METHODS section
    //

    // get/create the method codeblock
    // public methods
    HierarchicalCodeBlock * pubMethodsBlock = publicBlock->getHierarchicalCodeBlock(QLatin1String("pubMethodsBlock"), QString(), 1);
    CodeComment * pubMethodsComment = pubMethodsBlock->getComment();
    bool forceDoc = pol->getCodeVerboseDocumentComments();
    // set conditions for showing this comment
    if (!forceDoc && !hasClassFields() && !hasOperationMethods)
        pubMethodsComment->setWriteOutText(false);
    else
        pubMethodsComment->setWriteOutText(true);

    // protected methods
    HierarchicalCodeBlock * protMethodsBlock = protectedBlock->getHierarchicalCodeBlock(QLatin1String("protMethodsBlock"), QString(), 1);
    CodeComment * protMethodsComment = protMethodsBlock->getComment();
    // set conditions for showing this comment
    if (!forceDoc && !hasClassFields() && !hasOperationMethods)
        protMethodsComment->setWriteOutText(false);
    else
        protMethodsComment->setWriteOutText(true);

    // private methods
    HierarchicalCodeBlock * privMethodsBlock = privateBlock->getHierarchicalCodeBlock(QLatin1String("privMethodsBlock"), QString(), 1);
    CodeComment * privMethodsComment = privMethodsBlock->getComment();
    // set conditions for showing this comment
    if (!forceDoc && !hasClassFields() && !hasOperationMethods)
        privMethodsComment->setWriteOutText(false);
    else
        privMethodsComment->setWriteOutText(true);

    // METHODS sub-section : constructor methods
    //

    // public
    pubConstructorBlock = pubMethodsBlock->getHierarchicalCodeBlock(QLatin1String("constructionMethods"), QLatin1String("Constructors"), 1);
    // special condiions for showing comment: only when autogenerateding empty constructors
    // Although, we *should* check for other constructor methods too
    CodeComment * pubConstComment = pubConstructorBlock->getComment();
    if (!forceDoc && (isInterface || !pol->getAutoGenerateConstructors()))
        pubConstComment->setWriteOutText(false);
    else
        pubConstComment->setWriteOutText(true);

    // protected
    protConstructorBlock = protMethodsBlock->getHierarchicalCodeBlock(QLatin1String("constructionMethods"), QLatin1String("Constructors"), 1);
    // special condiions for showing comment: only when autogenerateding empty constructors
    // Although, we *should* check for other constructor methods too
    CodeComment * protConstComment = protConstructorBlock->getComment();
    if (!forceDoc && (isInterface || !pol->getAutoGenerateConstructors()))
        protConstComment->setWriteOutText(false);
    else
        protConstComment->setWriteOutText(true);

    // private
    privConstructorBlock = privMethodsBlock->getHierarchicalCodeBlock(QLatin1String("constructionMethods"), QLatin1String("Constructors"), 1);
    // special condiions for showing comment: only when autogenerateding empty constructors
    // Although, we *should* check for other constructor methods too
    CodeComment * privConstComment = privConstructorBlock->getComment();
    if (!forceDoc && (isInterface || !pol->getAutoGenerateConstructors()))
        privConstComment->setWriteOutText(false);
    else
        privConstComment->setWriteOutText(true);

    // get/create the accessor codeblock
    // public
    HierarchicalCodeBlock * pubAccessorBlock = pubMethodsBlock->getHierarchicalCodeBlock(QLatin1String("accessorMethods"), QLatin1String("Accessor Methods"), 1);
    // set conditions for showing section comment
    CodeComment * pubAccessComment = pubAccessorBlock->getComment();
    if (!forceDoc && !hasClassFields())
        pubAccessComment->setWriteOutText(false);
    else
        pubAccessComment->setWriteOutText(true);

    // protected
    HierarchicalCodeBlock * protAccessorBlock = protMethodsBlock->getHierarchicalCodeBlock(QLatin1String("accessorMethods"), QLatin1String("Accessor Methods"), 1);
    // set conditions for showing section comment
    CodeComment * protAccessComment = protAccessorBlock->getComment();
    if (!forceDoc && !hasClassFields())
        protAccessComment->setWriteOutText(false);
    else
        protAccessComment->setWriteOutText(true);

    // private
    HierarchicalCodeBlock * privAccessorBlock = privMethodsBlock->getHierarchicalCodeBlock(QLatin1String("accessorMethods"), QLatin1String("Accessor Methods"), 1);
    // set conditions for showing section comment
    CodeComment * privAccessComment = privAccessorBlock->getComment();
    if (!forceDoc && !hasClassFields())
        privAccessComment->setWriteOutText(false);
    else
        privAccessComment->setWriteOutText(true);

    // now, 2 sub-sub sections in accessor block
    // add/update accessor methods for attributes
    HierarchicalCodeBlock * pubStaticAccessors = pubAccessorBlock->getHierarchicalCodeBlock(QLatin1String("pubStaticAccessorMethods"), QString(), 1);
    HierarchicalCodeBlock * pubRegularAccessors = pubAccessorBlock->getHierarchicalCodeBlock(QLatin1String("pubRegularAccessorMethods"), QString(), 1);
    pubStaticAccessors->getComment()->setWriteOutText(false); // never write block comment
    pubRegularAccessors->getComment()->setWriteOutText(false); // never write block comment

    HierarchicalCodeBlock * protStaticAccessors = protAccessorBlock->getHierarchicalCodeBlock(QLatin1String("protStaticAccessorMethods"), QString(), 1);
    HierarchicalCodeBlock * protRegularAccessors = protAccessorBlock->getHierarchicalCodeBlock(QLatin1String("protRegularAccessorMethods"), QString(), 1);
    protStaticAccessors->getComment()->setWriteOutText(false); // never write block comment
    protRegularAccessors->getComment()->setWriteOutText(false); // never write block comment

    HierarchicalCodeBlock * privStaticAccessors = privAccessorBlock->getHierarchicalCodeBlock(QLatin1String("privStaticAccessorMethods"), QString(), 1);
    HierarchicalCodeBlock * privRegularAccessors = privAccessorBlock->getHierarchicalCodeBlock(QLatin1String("privRegularAccessorMethods"), QString(), 1);
    privStaticAccessors->getComment()->setWriteOutText(false); // never write block comment
    privRegularAccessors->getComment()->setWriteOutText(false); // never write block comment
    // now add in accessors as appropriate

    // public stuff
    pubStaticAccessors->addCodeClassFieldMethods(staticPublicAttribClassFields);
    pubRegularAccessors->addCodeClassFieldMethods(publicAttribClassFields);
    pubRegularAccessors->addCodeClassFieldMethods(publicPlainAssocClassFields);
    pubRegularAccessors->addCodeClassFieldMethods(publicAggregationClassFields);
    pubRegularAccessors->addCodeClassFieldMethods(publicCompositionClassFields);

    // protected stuff
    protStaticAccessors->addCodeClassFieldMethods(staticProtectedAttribClassFields);
    protRegularAccessors->addCodeClassFieldMethods(protectedAttribClassFields);
    protRegularAccessors->addCodeClassFieldMethods(protPlainAssocClassFields);
    protRegularAccessors->addCodeClassFieldMethods(protAggregationClassFields);
    protRegularAccessors->addCodeClassFieldMethods(protCompositionClassFields);

    // private stuff
    privStaticAccessors->addCodeClassFieldMethods(staticPrivateAttribClassFields);
    privRegularAccessors->addCodeClassFieldMethods(privateAttribClassFields);
    privRegularAccessors->addCodeClassFieldMethods(privPlainAssocClassFields);
    privRegularAccessors->addCodeClassFieldMethods(privAggregationClassFields);
    privRegularAccessors->addCodeClassFieldMethods(privCompositionClassFields);

    // METHODS subsection : Operation methods (which aren't constructors)
    //

    // setup/get/create the operations codeblock

    // public
    pubOperationsBlock = pubMethodsBlock->getHierarchicalCodeBlock(QLatin1String("operationMethods"), QLatin1String("Operations"), 1);
    // set conditions for showing section comment
    CodeComment * pubOcomment = pubOperationsBlock->getComment();
    if (!forceDoc && !hasOperationMethods)
        pubOcomment->setWriteOutText(false);
    else
        pubOcomment->setWriteOutText(true);

    //protected
    protOperationsBlock = protMethodsBlock->getHierarchicalCodeBlock(QLatin1String("operationMethods"), QLatin1String("Operations"), 1);
    // set conditions for showing section comment
    CodeComment * protOcomment = protOperationsBlock->getComment();
    if (!forceDoc && !hasOperationMethods)
        protOcomment->setWriteOutText(false);
    else
        protOcomment->setWriteOutText(true);

    //private
    privOperationsBlock = privMethodsBlock->getHierarchicalCodeBlock(QLatin1String("operationMethods"), QLatin1String("Operations"), 1);
    // set conditions for showing section comment
    CodeComment * privOcomment = privOperationsBlock->getComment();
    if (!forceDoc && !hasOperationMethods)
        privOcomment->setWriteOutText(false);
    else
        privOcomment->setWriteOutText(true);
}
// This method will cause the class to rebuild its text representation.
// based on the parent classifier object.
// For any situation in which this is called, we are either building the code
// document up, or replacing/regenerating the existing auto-generated parts. As
// such, we will want to insert everything we resonablely will want
// during creation. We can set various parts of the document (esp. the
// comments) to appear or not, as needed.
void CPPHeaderCodeDocument::updateContent()
{
    // Gather info on the various fields and parent objects of this class...
    UMLClassifier * c = getParentClassifier();
    Q_ASSERT(c != NULL);
    CodeGenPolicyExt *pe = UMLApp::app()->policyExt();
    CPPCodeGenerationPolicy * policy = dynamic_cast<CPPCodeGenerationPolicy*>(pe);

    // first, set the global flag on whether or not to show classfield info
    const CodeClassFieldList * cfList = getCodeClassFieldList();
    CodeClassFieldList::const_iterator it = cfList->begin();
    CodeClassFieldList::const_iterator end = cfList->end();
    for(; it != end; ++it)
        (*it)->setWriteOutMethods(policy->getAutoGenerateAccessors());

    // attribute-based ClassFields
    // we do it this way to have the static fields sorted out from regular ones
    CodeClassFieldList staticPublicAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true, Uml::Visibility::Public);
    CodeClassFieldList publicAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, false, Uml::Visibility::Public);
    CodeClassFieldList staticProtectedAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true, Uml::Visibility::Protected);
    CodeClassFieldList protectedAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, false, Uml::Visibility::Protected);
    CodeClassFieldList staticPrivateAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true, Uml::Visibility::Private);
    CodeClassFieldList privateAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, false, Uml::Visibility::Private);

    // association-based ClassFields
    // don't care if they are static or not..all are lumped together
    CodeClassFieldList publicPlainAssocClassFields = getSpecificClassFields (CodeClassField::PlainAssociation, Uml::Visibility::Public);
    CodeClassFieldList publicAggregationClassFields = getSpecificClassFields (CodeClassField::Aggregation, Uml::Visibility::Public);
    CodeClassFieldList publicCompositionClassFields = getSpecificClassFields (CodeClassField::Composition, Uml::Visibility::Public);

    CodeClassFieldList protPlainAssocClassFields = getSpecificClassFields (CodeClassField::PlainAssociation, Uml::Visibility::Protected);
    CodeClassFieldList protAggregationClassFields = getSpecificClassFields (CodeClassField::Aggregation, Uml::Visibility::Protected);
    CodeClassFieldList protCompositionClassFields = getSpecificClassFields (CodeClassField::Composition, Uml::Visibility::Protected);

    CodeClassFieldList privPlainAssocClassFields = getSpecificClassFields (CodeClassField::PlainAssociation, Uml::Visibility::Private);
    CodeClassFieldList privAggregationClassFields = getSpecificClassFields (CodeClassField::Aggregation, Uml::Visibility::Private);
    CodeClassFieldList privCompositionClassFields = getSpecificClassFields (CodeClassField::Composition, Uml::Visibility::Private);

    bool hasOperationMethods = false;
    UMLOperationList list = c->getOpList();
    hasOperationMethods = ! list.isEmpty();

    bool hasNamespace = false;
    bool isEnumeration = false;
    bool isInterface = parentIsInterface();
    bool hasclassFields = hasClassFields();
    bool forcedoc = UMLApp::app()->commonPolicy()->getCodeVerboseDocumentComments();
    QString endLine = UMLApp::app()->commonPolicy()->getNewLineEndingChars();

    UMLClassifierList superclasses = c->findSuperClassConcepts();


    // START GENERATING CODE/TEXT BLOCKS and COMMENTS FOR THE DOCUMENT
    //

    // Write the hash define stuff to prevent multiple parsing/inclusion of header
    QString cppClassName = CodeGenerator::cleanName(c->name());
    QString hashDefine = CodeGenerator::cleanName(c->name().toUpper().simplified());
    QString defText = QLatin1String("#ifndef ") + hashDefine + QLatin1String("_H") + endLine + QLatin1String("#define ") + hashDefine + QLatin1String("_H");
    addOrUpdateTaggedCodeBlockWithComments(QLatin1String("hashDefBlock"), defText, QString(), 0, false);

    // INCLUDE CODEBLOCK
    //
    // Q: Why all utils? Isnt just List and Vector the only classes we are using?
    // A: doesn't matter at all; its more readable to just include '*' and cpp compilers
    //    don't slow down or anything. (TZ)
    QString includeStatement;
    bool stringGlobal = policy->stringIncludeIsGlobal();
    QString sStartBrak = stringGlobal ? QLatin1String("<") : QLatin1String("\"");
    QString sEndBrak = stringGlobal ? QLatin1String(">") : QLatin1String("\"");
    includeStatement.append(QLatin1String("#include ") + sStartBrak + policy->getStringClassNameInclude() + sEndBrak + endLine);
    if (hasObjectVectorClassFields())
    {
        bool vecGlobal = policy->vectorIncludeIsGlobal();
        QString vStartBrak = vecGlobal ? QLatin1String("<") : QLatin1String("\"");
        QString vEndBrak = vecGlobal ? QLatin1String(">") : QLatin1String("\"");
        QString value =QLatin1String("#include ") + vStartBrak + policy->getVectorClassNameInclude() + vEndBrak;
        includeStatement.append(value + endLine);
    }

    //only include classes in a different package from this class
    UMLPackageList includes;
    QMap<UMLPackage *, QString> packageMap; // so we don't repeat packages

    CodeGenerator::findObjectsRelated(c, includes);
    foreach(UMLPackage* con, includes) {
        if (con->baseType() != UMLObject::ot_Datatype && !packageMap.contains(con)) {
            packageMap.insert(con, con->package());
            if(con != getParentClassifier())
                includeStatement.append(QLatin1String("#include \"") + CodeGenerator::cleanName(con->name().toLower()) + QLatin1String(".h\"") + endLine);
        }
    }
    // now, add/update the includes codeblock
    CodeBlockWithComments * inclBlock = addOrUpdateTaggedCodeBlockWithComments(QLatin1String("includes"), includeStatement, QString(), 0, false);
    if(includeStatement.isEmpty() && inclBlock->contentType() == CodeBlock::AutoGenerated)
        inclBlock->setWriteOutText(false);
    else
        inclBlock->setWriteOutText(true);

    // Using
    QString usingStatement;
    foreach(UMLClassifier* classifier, superclasses) {
        if(classifier->package()!=c->package() && !classifier->package().isEmpty()) {
            usingStatement.append(QLatin1String("using ") + CodeGenerator::cleanName(c->package()) + QLatin1String("::") + cleanName(c->name()) + QLatin1Char(';') + endLine);
        }
    }
    CodeBlockWithComments * usingBlock = addOrUpdateTaggedCodeBlockWithComments(QLatin1String("using"), usingStatement, QString(), 0, false);
    if(usingStatement.isEmpty() && usingBlock->contentType() == CodeBlock::AutoGenerated)
        usingBlock->setWriteOutText(false);
    else
        usingBlock->setWriteOutText(true);

    // namespace
    // This needs special treatment. We cant use "nowriteouttext" for this, as
    // that will prevent the class declaration from being written. Instead, we
    // check if "hasNamspace" is true or not, and then indent the remaining code
    // appropriately as well as set the start/end text of this namespace block.
    if (c->umlPackage() && policy->getPackageIsNamespace())
        hasNamespace = true;
    else
        hasNamespace = false;

    // set start/end text of namespace block
    m_namespaceBlock = getHierarchicalCodeBlock(QLatin1String("namespace"), QLatin1String("Namespace"), 0);
    if(hasNamespace) {
        UMLPackageList pkgList = c->packages();
        QString pkgs;
        UMLPackage *pkg;
        foreach (pkg, pkgList) {
            pkgs += QLatin1String("namespace ") + CodeGenerator::cleanName(pkg->name()) + QLatin1String(" { ");
        }
        m_namespaceBlock->setStartText(pkgs);
        QString closingBraces;
        foreach (pkg, pkgList) {
            closingBraces += QLatin1String("} ");
        }
// This method will cause the class to rebuild its text representation.
// based on the parent classifier object.
// For any situation in which this is called, we are either building the code
// document up, or replacing/regenerating the existing auto-generated parts. As
// such, we will want to insert everything we resonablely will want
// during creation. We can set various parts of the document (esp. the
// comments) to appear or not, as needed.
void CPPHeaderCodeDocument::updateContent( )
{
    // Gather info on the various fields and parent objects of this class...
    UMLClassifier * c = getParentClassifier();
    CodeGenPolicyExt *pe = UMLApp::app()->getPolicyExt();
    CPPCodeGenerationPolicy * policy = dynamic_cast<CPPCodeGenerationPolicy*>(pe);

    // first, set the global flag on whether or not to show classfield info
    CodeClassFieldList * cfList = getCodeClassFieldList();
    for(CodeClassField * field = cfList->first(); field; field = cfList->next())
        field->setWriteOutMethods(policy->getAutoGenerateAccessors());

    // attribute-based ClassFields
    // we do it this way to have the static fields sorted out from regular ones
    CodeClassFieldList staticPublicAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true, Uml::Visibility::Public );
    CodeClassFieldList publicAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, false, Uml::Visibility::Public );
    CodeClassFieldList staticProtectedAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true, Uml::Visibility::Protected );
    CodeClassFieldList protectedAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, false, Uml::Visibility::Protected );
    CodeClassFieldList staticPrivateAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true, Uml::Visibility::Private );
    CodeClassFieldList privateAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, false, Uml::Visibility::Private);

    // association-based ClassFields
    // don't care if they are static or not..all are lumped together
    CodeClassFieldList publicPlainAssocClassFields = getSpecificClassFields ( CodeClassField::PlainAssociation , Uml::Visibility::Public);
    CodeClassFieldList publicAggregationClassFields = getSpecificClassFields ( CodeClassField::Aggregation, Uml::Visibility::Public);
    CodeClassFieldList publicCompositionClassFields = getSpecificClassFields ( CodeClassField::Composition, Uml::Visibility::Public );

    CodeClassFieldList protPlainAssocClassFields = getSpecificClassFields ( CodeClassField::PlainAssociation , Uml::Visibility::Protected);
    CodeClassFieldList protAggregationClassFields = getSpecificClassFields ( CodeClassField::Aggregation, Uml::Visibility::Protected);
    CodeClassFieldList protCompositionClassFields = getSpecificClassFields ( CodeClassField::Composition, Uml::Visibility::Protected);

    CodeClassFieldList privPlainAssocClassFields = getSpecificClassFields ( CodeClassField::PlainAssociation , Uml::Visibility::Private);
    CodeClassFieldList privAggregationClassFields = getSpecificClassFields ( CodeClassField::Aggregation, Uml::Visibility::Private);
    CodeClassFieldList privCompositionClassFields = getSpecificClassFields ( CodeClassField::Composition, Uml::Visibility::Private);

    bool hasOperationMethods = c->getOpList().last() ? true : false;
    bool hasNamespace = false;
    bool isEnumeration = false;
    bool isInterface = parentIsInterface();
    bool hasclassFields = hasClassFields();
    bool forcedoc = UMLApp::app()->getCommonPolicy()->getCodeVerboseDocumentComments();
    QString endLine = UMLApp::app()->getCommonPolicy()->getNewLineEndingChars();

    UMLClassifierList superclasses = c->findSuperClassConcepts();


    // START GENERATING CODE/TEXT BLOCKS and COMMENTS FOR THE DOCUMENT
    //

    // Write the hash define stuff to prevent multiple parsing/inclusion of header
    QString cppClassName = CodeGenerator::cleanName(c->getName());
    QString hashDefine = CodeGenerator::cleanName(c->getName().upper().simplifyWhiteSpace());
    QString defText = "#ifndef "+hashDefine + "_H"+ endLine + "#define "+ hashDefine + "_H";
    addOrUpdateTaggedCodeBlockWithComments("hashDefBlock", defText, "", 0, false);

    // INCLUDE CODEBLOCK
    //
    // Q: Why all utils? Isnt just List and Vector the only classes we are using?
    // A: doesn't matter at all; its more readable to just include '*' and cpp compilers
    //    don't slow down or anything. (TZ)
    QString includeStatement = "";
    bool stringGlobal = policy->stringIncludeIsGlobal();
    QString sStartBrak = stringGlobal ? "<" : "\"";
    QString sEndBrak = stringGlobal ? ">" : "\"";
    includeStatement.append("#include "+sStartBrak+policy->getStringClassNameInclude()+sEndBrak+endLine);
    if ( hasObjectVectorClassFields() )
    {
        bool vecGlobal = policy->vectorIncludeIsGlobal();
        QString vStartBrak = vecGlobal ? "<" : "\"";
        QString vEndBrak = vecGlobal ? ">" : "\"";
        QString value ="#include "+vStartBrak+policy->getVectorClassNameInclude()+vEndBrak;
        includeStatement.append(value+endLine);
    }

    //only include classes in a different package from this class
    UMLPackageList includes;
    QMap<UMLPackage *,QString> packageMap; // so we don't repeat packages

    CodeGenerator::findObjectsRelated(c,includes);
    for(UMLPackage *con = includes.first(); con ; con = includes.next())
        if (con->getBaseType() != Uml::ot_Datatype && !packageMap.contains(con))
        {
            packageMap.insert(con,con->getPackage());
            if(con != getParentClassifier())
                includeStatement.append("#include \""+CodeGenerator::cleanName(con->getName().lower())+".h\""+endLine);
        }
    // now, add/update the includes codeblock
    CodeBlockWithComments * inclBlock = addOrUpdateTaggedCodeBlockWithComments("includes", includeStatement, QString::null, 0, false);
    if(includeStatement.isEmpty() && inclBlock->getContentType() == CodeBlock::AutoGenerated)
        inclBlock->setWriteOutText(false);
    else
        inclBlock->setWriteOutText(true);

    // Using
    QString usingStatement;
    for(UMLClassifier *classifier = superclasses.first(); classifier ; classifier = superclasses.next()) {
        if(classifier->getPackage()!=c->getPackage() && !classifier->getPackage().isEmpty()) {
            usingStatement.append("using "+CodeGenerator::cleanName(c->getPackage())+"::"+cleanName(c->getName())+';'+endLine);
        }
    }
    CodeBlockWithComments * usingBlock = addOrUpdateTaggedCodeBlockWithComments("using", usingStatement, "", 0, false);
    if(usingStatement.isEmpty() && usingBlock->getContentType() == CodeBlock::AutoGenerated)
        usingBlock->setWriteOutText(false);
    else
        usingBlock->setWriteOutText(true);

    // namespace
    // This needs special treatment. We cant use "nowriteouttext" for this, as
    // that will prevent the class declaration from being written. Instead, we
    // check if "hasNamspace" is true or not, and then indent the remaining code
    // appropriately as well as set the start/end text of this namespace block.
    if (c->getUMLPackage() && policy->getPackageIsNamespace())
        hasNamespace = true;
    else
        hasNamespace = false;

    // set start/end text of namespace block
    namespaceBlock = getHierarchicalCodeBlock("namespace", "Namespace", 0);
    if(hasNamespace) {
        UMLPackageList pkgList = c->getPackages();
        QString pkgs;
        UMLPackage *pkg;
        for (pkg = pkgList.first(); pkg != NULL; pkg = pkgList.next()) {
            pkgs += "namespace " + CodeGenerator::cleanName(pkg->getName()) + " { ";
        }
        namespaceBlock->setStartText(pkgs);
        QString closingBraces;
        for (pkg = pkgList.first(); pkg != NULL; pkg = pkgList.next()) {
            closingBraces += "} ";
        }
        namespaceBlock->setEndText(closingBraces);
        namespaceBlock->getComment()->setWriteOutText(true);
    } else {
        namespaceBlock->setStartText("");
        namespaceBlock->setEndText("");
        namespaceBlock->getComment()->setWriteOutText(false);
    }

    // Enum types for include
    if (!isInterface) {
        QString enumStatement;
        QString indent = UMLApp::app()->getCommonPolicy()->getIndentation();
        UMLEnum* e = dynamic_cast<UMLEnum*>(c);
        if (e) {
            enumStatement.append(indent + "enum " + cppClassName + " {" + endLine);

            // populate
            UMLClassifierListItemList ell = e->getFilteredList(Uml::ot_EnumLiteral);
            for (UMLClassifierListItem *el=ell.first(); el ; ) {
                enumStatement.append(indent+indent);
                enumStatement.append(CodeGenerator::cleanName(el->getName()));
                if ((el=ell.next()) != 0)
                    enumStatement.append(", "+endLine);
                else
                    break;
                enumStatement.append(endLine);
            }
            enumStatement.append(indent+"};");
            isEnumeration = true;
        }
        namespaceBlock->addOrUpdateTaggedCodeBlockWithComments("enums", enumStatement, "", 0, false);
    }

    // CLASS DECLARATION BLOCK
    //

    // add the class declaration block to the namespace block.
    CPPHeaderClassDeclarationBlock * myClassDeclCodeBlock = getClassDecl();
    namespaceBlock->addTextBlock(myClassDeclCodeBlock); // note: wont add if already present

    // Is this really true?? hmm..
    if(isEnumeration)
        myClassDeclCodeBlock->setWriteOutText(false); // not written out IF its an enumeration class
    else
        myClassDeclCodeBlock->setWriteOutText(true);

    //
    // Main Sub-Blocks
    //

    // declare public, protected and private methods, attributes (fields).
    // set the start text ONLY if this is the first time we created the objects.
    bool createdPublicBlock = publicBlock == 0 ? true : false;
    publicBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock("publicBlock","Public stuff",0);
    if (createdPublicBlock)
        publicBlock->setStartText("public:");

    bool createdProtBlock = protectedBlock == 0 ? true : false;
    protectedBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock("protectedBlock","Protected stuff",0);
    if(createdProtBlock)
        protectedBlock->setStartText("protected:");

    bool createdPrivBlock = privateBlock == 0 ? true : false;
    privateBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock("privateBlock","Private stuff",0);
    if(createdPrivBlock)
        privateBlock->setStartText("private:");

    //
    // * CLASS FIELD declaration section
    //

    // setup/get/create the field declaration code block
    //

    // public fields: Update the comment: we only set comment to appear under the following conditions
    HierarchicalCodeBlock * publicFieldDeclBlock = publicBlock->getHierarchicalCodeBlock("publicFieldsDecl", "Fields", 1);
    CodeComment * pubFcomment = publicFieldDeclBlock->getComment();
    if (!forcedoc && !hasclassFields )
        pubFcomment->setWriteOutText(false);
    else
        pubFcomment->setWriteOutText(true);

    // protected fields: Update the comment: we only set comment to appear under the following conditions
    HierarchicalCodeBlock * protectedFieldDeclBlock = protectedBlock->getHierarchicalCodeBlock("protectedFieldsDecl", "Fields", 1);
    CodeComment * protFcomment = protectedFieldDeclBlock->getComment();
    if (!forcedoc && !hasclassFields )
        protFcomment->setWriteOutText(false);
    else
        protFcomment->setWriteOutText(true);

    // private fields: Update the comment: we only set comment to appear under the following conditions
    HierarchicalCodeBlock * privateFieldDeclBlock = privateBlock->getHierarchicalCodeBlock("privateFieldsDecl", "Fields", 1);
    CodeComment * privFcomment = privateFieldDeclBlock->getComment();
    if (!forcedoc && !hasclassFields )
        privFcomment->setWriteOutText(false);
    else
        privFcomment->setWriteOutText(true);


    // now actually declare the fields within the appropriate HCodeBlock
    //

    // public
    declareClassFields(staticPublicAttribClassFields, publicFieldDeclBlock);
    declareClassFields(publicAttribClassFields, publicFieldDeclBlock);
    declareClassFields(publicPlainAssocClassFields, publicFieldDeclBlock);
    declareClassFields(publicAggregationClassFields, publicFieldDeclBlock);
    declareClassFields(publicCompositionClassFields, publicFieldDeclBlock);

    // protected
    declareClassFields(staticProtectedAttribClassFields, protectedFieldDeclBlock);
    declareClassFields(protectedAttribClassFields, protectedFieldDeclBlock);
    declareClassFields(protPlainAssocClassFields, protectedFieldDeclBlock);
    declareClassFields(protAggregationClassFields, protectedFieldDeclBlock);
    declareClassFields(protCompositionClassFields, protectedFieldDeclBlock);

    // private
    declareClassFields(staticPrivateAttribClassFields, privateFieldDeclBlock);
    declareClassFields(privateAttribClassFields, privateFieldDeclBlock);
    declareClassFields(privPlainAssocClassFields, privateFieldDeclBlock);
    declareClassFields(privAggregationClassFields, privateFieldDeclBlock);
    declareClassFields(privCompositionClassFields, privateFieldDeclBlock);

    //
    // METHODS section
    //

    // get/create the method codeblock

    // public methods
    HierarchicalCodeBlock * pubMethodsBlock = publicBlock->getHierarchicalCodeBlock("pubMethodsBlock", "", 1);
    CodeComment * pubMethodsComment = pubMethodsBlock->getComment();
    // set conditions for showing this comment
    if (!forcedoc && !hasclassFields && !hasOperationMethods)
        pubMethodsComment->setWriteOutText(false);
    else
        pubMethodsComment->setWriteOutText(true);

    // protected methods
    HierarchicalCodeBlock * protMethodsBlock = protectedBlock->getHierarchicalCodeBlock("protMethodsBlock", "", 1);
    CodeComment * protMethodsComment = protMethodsBlock->getComment();
    // set conditions for showing this comment
    if (!forcedoc && !hasclassFields && !hasOperationMethods)
        protMethodsComment->setWriteOutText(false);
    else
        protMethodsComment->setWriteOutText(true);

    // private methods
    HierarchicalCodeBlock * privMethodsBlock = privateBlock->getHierarchicalCodeBlock("privMethodsBlock", "", 1);
    CodeComment * privMethodsComment = privMethodsBlock->getComment();
    // set conditions for showing this comment
    if (!forcedoc && !hasclassFields && !hasOperationMethods)
        privMethodsComment->setWriteOutText(false);
    else
        privMethodsComment->setWriteOutText(true);


    // METHODS sub-section : constructor methods
    //
    CodeGenerationPolicy *pol = UMLApp::app()->getCommonPolicy();

    // setup/get/create the constructor codeblocks

    // public
    pubConstructorBlock = pubMethodsBlock->getHierarchicalCodeBlock("constructionMethods", "Constructors", 1);
    // special condiions for showing comment: only when autogenerateding empty constructors
    // Although, we *should* check for other constructor methods too
    CodeComment * pubConstComment = pubConstructorBlock->getComment();
    if (!forcedoc && (isInterface || !pol->getAutoGenerateConstructors()))
        pubConstComment->setWriteOutText(false);
    else
        pubConstComment->setWriteOutText(true);

    // protected
    protConstructorBlock = protMethodsBlock->getHierarchicalCodeBlock("constructionMethods", "Constructors", 1);
    // special condiions for showing comment: only when autogenerateding empty constructors
    // Although, we *should* check for other constructor methods too
    CodeComment * protConstComment = protConstructorBlock->getComment();
    if (!forcedoc && (isInterface || !pol->getAutoGenerateConstructors()))
        protConstComment->setWriteOutText(false);
    else
        protConstComment->setWriteOutText(true);

    // private
    privConstructorBlock = privMethodsBlock->getHierarchicalCodeBlock("constructionMethods", "Constructors", 1);
    // special condiions for showing comment: only when autogenerateding empty constructors
    // Although, we *should* check for other constructor methods too
    CodeComment * privConstComment = privConstructorBlock->getComment();
    if (!forcedoc && (isInterface || !pol->getAutoGenerateConstructors()))
        privConstComment->setWriteOutText(false);
    else
        privConstComment->setWriteOutText(true);

    // add/get the empty constructor. I guess since there is no
    // meta-data to state what the scope of this method is, we will make it
    // "public" as a default. This might present problems if the user wants
    // to move the block into the "private" or "protected" blocks.
    QString emptyConstStatement = cppClassName + " ( ) { }";

    // search for this first in the entire document. IF not present, put
    // it in the public constructor method block
    TextBlock * emptyConstTb = findTextBlockByTag("emptyconstructor", true);
    CodeBlockWithComments * emptyConstBlock = dynamic_cast<CodeBlockWithComments*>(emptyConstTb);
    if(!emptyConstBlock)
        emptyConstBlock = pubConstructorBlock->addOrUpdateTaggedCodeBlockWithComments("emptyconstructor", emptyConstStatement, "Empty Constructor", 1, false);

    // Now, as an additional condition we only show the empty constructor block
    // IF it was desired to be shown
    if(!isInterface && pol->getAutoGenerateConstructors())
        emptyConstBlock->setWriteOutText(true);
    else
        emptyConstBlock->setWriteOutText(false);


    // METHODS subsection : ACCESSOR METHODS
    //

    // get/create the accessor codeblock

    // public
    HierarchicalCodeBlock * pubAccessorBlock = pubMethodsBlock->getHierarchicalCodeBlock("accessorMethods", "Accessor Methods", 1);
    // set conditions for showing section comment
    CodeComment * pubAccessComment = pubAccessorBlock->getComment();
    if (!forcedoc && !hasclassFields)
        pubAccessComment->setWriteOutText(false);
    else
        pubAccessComment->setWriteOutText(true);

    // protected
    HierarchicalCodeBlock * protAccessorBlock = protMethodsBlock->getHierarchicalCodeBlock("accessorMethods", "Accessor Methods", 1);
    // set conditions for showing section comment
    CodeComment * protAccessComment = protAccessorBlock->getComment();
    if (!forcedoc && !hasclassFields)
        protAccessComment->setWriteOutText(false);
    else
        protAccessComment->setWriteOutText(true);

    // private
    HierarchicalCodeBlock * privAccessorBlock = privMethodsBlock->getHierarchicalCodeBlock("accessorMethods", "Accessor Methods", 1);
    // set conditions for showing section comment
    CodeComment * privAccessComment = privAccessorBlock->getComment();
    // We've to copy the private accessorMethods to the public block
    if (!forcedoc && !hasclassFields)
        privAccessComment->setWriteOutText(false);
    else
        privAccessComment->setWriteOutText(true);

    // now, 2 sub-sub sections in accessor block
    // add/update accessor methods for attributes
    HierarchicalCodeBlock * pubStaticAccessors = pubAccessorBlock->getHierarchicalCodeBlock("pubStaticAccessorMethods", "", 1);
    HierarchicalCodeBlock * pubRegularAccessors = pubAccessorBlock->getHierarchicalCodeBlock("pubRegularAccessorMethods", "", 1);
    pubStaticAccessors->getComment()->setWriteOutText(false); // never write block comment
    pubRegularAccessors->getComment()->setWriteOutText(false); // never write block comment

    HierarchicalCodeBlock * protStaticAccessors = protAccessorBlock->getHierarchicalCodeBlock("protStaticAccessorMethods", "", 1);
    HierarchicalCodeBlock * protRegularAccessors = protAccessorBlock->getHierarchicalCodeBlock("protRegularAccessorMethods", "", 1);
    protStaticAccessors->getComment()->setWriteOutText(false); // never write block comment
    protRegularAccessors->getComment()->setWriteOutText(false); // never write block comment

    HierarchicalCodeBlock * privStaticAccessors = privAccessorBlock->getHierarchicalCodeBlock("privStaticAccessorMethods", "", 1);
    HierarchicalCodeBlock * privRegularAccessors = privAccessorBlock->getHierarchicalCodeBlock("privRegularAccessorMethods", "", 1);
    privStaticAccessors->getComment()->setWriteOutText(false); // never write block comment
    privRegularAccessors->getComment()->setWriteOutText(false); // never write block comment

    // now add in accessors as appropriate

    // public stuff
    pubStaticAccessors->addCodeClassFieldMethods(staticPublicAttribClassFields);
    pubRegularAccessors->addCodeClassFieldMethods(publicAttribClassFields);

    // generate accessors as public
    if (policy && policy->getAccessorsArePublic())
    {
        pubRegularAccessors->addCodeClassFieldMethods(privateAttribClassFields);
        pubRegularAccessors->addCodeClassFieldMethods(protectedAttribClassFields);
    }

    pubRegularAccessors->addCodeClassFieldMethods(publicPlainAssocClassFields);
    pubRegularAccessors->addCodeClassFieldMethods(publicAggregationClassFields);
    pubRegularAccessors->addCodeClassFieldMethods(publicCompositionClassFields);

    // protected stuff
    protStaticAccessors->addCodeClassFieldMethods(staticProtectedAttribClassFields);

    // accessors are public so we don't have to create it here
    if (policy && !policy->getAccessorsArePublic())
        protRegularAccessors->addCodeClassFieldMethods(protectedAttribClassFields);

    protRegularAccessors->addCodeClassFieldMethods(protPlainAssocClassFields);
    protRegularAccessors->addCodeClassFieldMethods(protAggregationClassFields);
    protRegularAccessors->addCodeClassFieldMethods(protCompositionClassFields);

    // private stuff
    privStaticAccessors->addCodeClassFieldMethods(staticPrivateAttribClassFields);

    // accessors are public so we don't have to create it here
    if (policy && !policy->getAccessorsArePublic())
        privRegularAccessors->addCodeClassFieldMethods(privateAttribClassFields);

    privRegularAccessors->addCodeClassFieldMethods(privPlainAssocClassFields);
    privRegularAccessors->addCodeClassFieldMethods(privAggregationClassFields);
    privRegularAccessors->addCodeClassFieldMethods(privCompositionClassFields);


    // METHODS subsection : Operation methods (e.g. methods derive from operations but which arent constructors)
    //

    // setup/get/create the operations codeblock

    // public
    pubOperationsBlock = pubMethodsBlock->getHierarchicalCodeBlock("operationMethods", "Operations", 1);
    // set conditions for showing section comment
    CodeComment * pubOcomment = pubOperationsBlock->getComment();
    if (!forcedoc && !hasOperationMethods )
        pubOcomment->setWriteOutText(false);
    else
        pubOcomment->setWriteOutText(true);

    //protected
    protOperationsBlock = protMethodsBlock->getHierarchicalCodeBlock("operationMethods", "Operations", 1);
    // set conditions for showing section comment
    CodeComment * protOcomment = protOperationsBlock->getComment();
    if (!forcedoc && !hasOperationMethods )
        protOcomment->setWriteOutText(false);
    else
        protOcomment->setWriteOutText(true);

    //private
    privOperationsBlock = privMethodsBlock->getHierarchicalCodeBlock("operationMethods", "Operations", 1);
    // set conditions for showing section comment
    CodeComment * privOcomment = privOperationsBlock->getComment();
    if (!forcedoc && !hasOperationMethods )
        privOcomment->setWriteOutText(false);
    else
        privOcomment->setWriteOutText(true);

    // Operations
    //
    // nothing to do here.. "updateOperations" in parent class puts things
    // in the right place using the "addCodeOperation" method we defined in this class

    // FINISH up with hash def block close
    QString defTextEnd = "#endif //"+hashDefine + "_H";
    addOrUpdateTaggedCodeBlockWithComments("hashDefBlockEnd", defTextEnd, "", 0, false);

}
Example #5
0
// This method will cause the class to rebuild its text representation.
// based on the parent classifier object.
// For any situation in which this is called, we are either building the code
// document up, or replacing/regenerating the existing auto-generated parts. As
// such, we will want to insert everything we resonablely will want
// during creation. We can set various parts of the document (esp. the
// comments) to appear or not, as needed.
void DClassifierCodeDocument::updateContent()
{
    // Gather info on the various fields and parent objects of this class...
    UMLClassifier * c = getParentClassifier();
    Q_ASSERT(c != 0);
    CodeGenerationPolicy * commonPolicy = UMLApp::app()->commonPolicy();
    CodeGenPolicyExt * pe = UMLApp::app()->policyExt();
    DCodeGenerationPolicy * policy = dynamic_cast<DCodeGenerationPolicy*>(pe);

    // first, set the global flag on whether or not to show classfield info
    // This depends on whether or not we have attribute/association classes
    const CodeClassFieldList * cfList = getCodeClassFieldList();
    CodeClassFieldList::const_iterator it = cfList->begin();
    CodeClassFieldList::const_iterator end = cfList->end();
    for (; it != end; ++it) {
        CodeClassField * field = *it;
        if (field->parentIsAttribute())
            field->setWriteOutMethods(policy->getAutoGenerateAttribAccessors());
        else
            field->setWriteOutMethods(policy->getAutoGenerateAssocAccessors());
    }

    // attribute-based ClassFields
    // we do it this way to have the static fields sorted out from regular ones
    CodeClassFieldList staticAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true);
    CodeClassFieldList attribClassFields = getSpecificClassFields (CodeClassField::Attribute, false);
    // association-based ClassFields
    // don't care if they are static or not..all are lumped together
    CodeClassFieldList plainAssocClassFields = getSpecificClassFields (CodeClassField::PlainAssociation);
    CodeClassFieldList aggregationClassFields = getSpecificClassFields (CodeClassField::Aggregation);
    CodeClassFieldList compositionClassFields = getSpecificClassFields (CodeClassField::Composition);

    bool isInterface = parentIsInterface();
    bool hasOperationMethods = false;

    UMLOperationList list = c->getOpList();
    hasOperationMethods = ! list.isEmpty();

    QString endLine = commonPolicy->getNewLineEndingChars(); // a shortcut..so we don't have to call this all the time

    //
    // START GENERATING CODE/TEXT BLOCKS and COMMENTS FOR THE DOCUMENT
    //

    //
    // PACKAGE CODE BLOCK
    //
    QString pkgs = getPackage();
    pkgs.replace(QRegExp(QLatin1String("::")), QLatin1String("."));
    QString packageText = getPackage().isEmpty() ? QString() : QString(QLatin1String("package ")+pkgs+QLatin1Char(';')+endLine);
    CodeBlockWithComments * pblock = addOrUpdateTaggedCodeBlockWithComments(QLatin1String("packages"), packageText, QString(), 0, false);
    if (packageText.isEmpty() && pblock->contentType() == CodeBlock::AutoGenerated)
        pblock->setWriteOutText(false);
    else
        pblock->setWriteOutText(true);

    // IMPORT CODEBLOCK
    //
    // Q: Why all utils? Aren't just List and Vector the only classes we are using?
    // A: doesn't matter at all; it is more readable to just include '*' and d compilers
    //    don't slow down or anything. (TZ)
    QString importStatement;
    if (hasObjectVectorClassFields())
        importStatement.append(QLatin1String("import d.util.*;"));

    //only import classes in a different package from this class
    UMLPackageList imports;
    QMap<UMLPackage*, QString> packageMap; // so we don't repeat packages

    CodeGenerator::findObjectsRelated(c, imports);
    for (UMLPackageListIt importsIt(imports); importsIt.hasNext();) {
        UMLPackage *con = importsIt.next();
        // NO (default) datatypes in the import statement.. use defined
        // ones whould be possible, but no idea how to do that...at least for now.
        // Dynamic casting is slow..not an optimal way to do this.
        if (!packageMap.contains(con) && !con->isUMLDatatype())
        {
            packageMap.insert(con, con->package());

            // now, we DON'T need to import classes that are already in our own package
            // (that is, IF a package is specified). Otherwise, we should have a declaration.
            if (con->package() != c->package() ||
                    (c->package().isEmpty() && con->package().isEmpty()))
            {
                importStatement.append(endLine+QLatin1String("import "));
                if (!con->package().isEmpty())
                    importStatement.append(con->package()+QLatin1Char('.'));
                importStatement.append(CodeGenerator::cleanName(con->name())+QLatin1Char(';'));
            }
        }
    }
    // now, add/update the imports codeblock
    CodeBlockWithComments * iblock = addOrUpdateTaggedCodeBlockWithComments(QLatin1String("imports"), importStatement, QString(), 0, false);
    if (importStatement.isEmpty() && iblock->contentType() == CodeBlock::AutoGenerated)
        iblock->setWriteOutText(false);
    else
        iblock->setWriteOutText(true);

    // CLASS DECLARATION BLOCK
    //

    // get the declaration block. If it is not already present, add it too
    DClassDeclarationBlock * myClassDeclCodeBlock = getClassDecl();
    addTextBlock(myClassDeclCodeBlock); // note: wont add if already present

    // NOW create document in sections..
    // now we want to populate the body of our class
    // our layout is the following general groupings of code blocks:

    // start d classifier document

    // header comment

    // package code block

    // import code block

    // class declaration

    //   section:
    //   - class field declaration section comment
    //   - class field declarations (0+ codeblocks)

    //   section:
    //   - methods section comment

    //     sub-section: constructor ops
    //     - constructor method section comment
    //     - constructor methods (0+ codeblocks)

    //     sub-section: accessors
    //     - accessor method section comment
    //     - static accessor methods (0+ codeblocks)
    //     - non-static accessor methods (0+ codeblocks)

    //     sub-section: non-constructor ops
    //     - operation method section comment
    //     - operations (0+ codeblocks)

    // end class declaration

    // end d classifier document


    // Q: Why use the more complicated scheme of arranging code blocks within codeblocks?
    // A: This will allow us later to preserve the format of our document so that if
    //    codeblocks are added, they may be easily added in the correct place, rather than at
    //    the end of the document, or by using a difficult algorithm to find the location of
    //    the last appropriate code block sibling (which may not exist.. for example user adds
    //    a constructor operation, but there currently are no constructor code blocks
    //    within the document).

    //
    // * CLASS FIELD declaration section
    //

    // get/create the field declaration code block
    HierarchicalCodeBlock * fieldDeclBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock(QLatin1String("fieldsDecl"), QLatin1String("Fields"), 1);

    // Update the comment: we only set comment to appear under the following conditions
    CodeComment * fcomment = fieldDeclBlock->getComment();
    if (isInterface || (!forceDoc() && !hasClassFields()))
        fcomment->setWriteOutText(false);
    else
        fcomment->setWriteOutText(true);

    // now actually declare the fields within the appropriate HCodeBlock
    declareClassFields(staticAttribClassFields, fieldDeclBlock);
    declareClassFields(attribClassFields, fieldDeclBlock);
    declareClassFields(plainAssocClassFields, fieldDeclBlock);
    declareClassFields(aggregationClassFields, fieldDeclBlock);
    declareClassFields(compositionClassFields, fieldDeclBlock);

    //
    // METHODS section
    //

    // get/create the method codeblock
    HierarchicalCodeBlock * methodsBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock(QLatin1String("methodsBlock"), QLatin1String("Methods"), 1);

    // Update the section comment
    CodeComment * methodsComment = methodsBlock->getComment();
    // set conditions for showing this comment
    if (!forceDoc() && !hasClassFields() && !hasOperationMethods)
        methodsComment->setWriteOutText(false);
    else
        methodsComment->setWriteOutText(true);

    // METHODS sub-section : constructor methods
    //

    // get/create the constructor codeblock
    HierarchicalCodeBlock * constBlock = methodsBlock->getHierarchicalCodeBlock(QLatin1String("constructorMethods"), QLatin1String("Constructors"), 1);
    constructorBlock = constBlock; // record this codeblock for later, when operations are updated

    // special condiions for showing comment: only when autogenerateding empty constructors
    // Although, we *should* check for other constructor methods too
    CodeComment * constComment = constBlock->getComment();
    CodeGenerationPolicy *pol = UMLApp::app()->commonPolicy();
    if (!forceDoc() && (isInterface || !pol->getAutoGenerateConstructors()))
        constComment->setWriteOutText(false);
    else
        constComment->setWriteOutText(true);

    // add/get the empty constructor
    QString DClassName = getDClassName(c->name());
    QString emptyConstStatement = QLatin1String("public ")+DClassName+QLatin1String(" () { }");
    CodeBlockWithComments * emptyConstBlock =
        constBlock->addOrUpdateTaggedCodeBlockWithComments(QLatin1String("emptyconstructor"), emptyConstStatement, QLatin1String("Empty Constructor"), 1, false);
    // Now, as an additional condition we only show the empty constructor block
    // IF it was desired to be shown
    if (parentIsClass() && pol->getAutoGenerateConstructors())
        emptyConstBlock->setWriteOutText(true);
    else
        emptyConstBlock->setWriteOutText(false);

    // METHODS subsection : ACCESSOR METHODS
    //

    // get/create the accessor codeblock
    HierarchicalCodeBlock * accessorBlock = methodsBlock->getHierarchicalCodeBlock(QLatin1String("accessorMethods"), QLatin1String("Accessor Methods"), 1);

    // set conditions for showing section comment
    CodeComment * accessComment = accessorBlock->getComment();
    if (!forceDoc() && !hasClassFields())
        accessComment->setWriteOutText(false);
    else
        accessComment->setWriteOutText(true);

    // now, 2 sub-sub sections in accessor block
    // add/update accessor methods for attributes
    HierarchicalCodeBlock * staticAccessors = accessorBlock->getHierarchicalCodeBlock(QLatin1String("staticAccessorMethods"), QString(), 1);
    staticAccessors->getComment()->setWriteOutText(false); // never write block comment
    staticAccessors->addCodeClassFieldMethods(staticAttribClassFields);
    staticAccessors->addCodeClassFieldMethods(attribClassFields);

    // add/update accessor methods for associations
    HierarchicalCodeBlock * regularAccessors = accessorBlock->getHierarchicalCodeBlock(QLatin1String("regularAccessorMethods"), QString(), 1);
    regularAccessors->getComment()->setWriteOutText(false); // never write block comment
    regularAccessors->addCodeClassFieldMethods(plainAssocClassFields);
    regularAccessors->addCodeClassFieldMethods(aggregationClassFields);
    regularAccessors->addCodeClassFieldMethods(compositionClassFields);

    // METHODS subsection : Operation methods (which arent constructors)
    //

    // get/create the operations codeblock
    operationsBlock = methodsBlock->getHierarchicalCodeBlock(QLatin1String("operationMethods"), QLatin1String("Operations"), 1);

    // set conditions for showing section comment
    CodeComment * ocomment = operationsBlock->getComment();
    if (!forceDoc() && !hasOperationMethods)
        ocomment->setWriteOutText(false);
    else
        ocomment->setWriteOutText(true);

}