// CCppClassMapGenerator.cpp
//
#include "stdafx.h"
#include "CSharpClassMapGenerator.h"
#include "XmlProjectSettings.h"
#include "XmlClassInfo.h"
#include "XmlMemberInfo.h"

CCSharpClassMapGenerator::CCSharpClassMapGenerator()
{}

CCSharpClassMapGenerator::~CCSharpClassMapGenerator()
{}


void CCSharpClassMapGenerator::Generate()
{
	// generate header file
	//
	//GenerateHeader();
	
	// generate implementation file
	//
	//GenerateImplementation();
}
	

/*****
void CCppClassMapGenerator::GenerateHeader()
{
	cmString fileName;
	cmString pathName;

	Head_generateHeader();
	Head_generateIfDefBegin();
	Head_generateIncludeSection();
	Head_generateForwardDecl();
	Head_generateClassBegin();
	Head_generateConstructor();
	Head_generateDestructor();
	Head_generateMethods();
	Head_generateSerialization();
	Head_generateMembers();
	Head_generateClassEnd();
	Head_generateIfDefEnd();

	pathName = BuildGeneratedSourcePath() + _T("include\\");
	fileName = GetClassName() + GetCardinalityPostfix(classInfo_) + _T(".h");
	SaveFile(pathName + fileName, headCode_);

	hGeneratedFiles_[fileName] = pathName + fileName;
}

void CCppClassMapGenerator::Head_generateHeader()
{
	headCode_ += _T("// ") + GetClassName() + GetCardinalityPostfix(classInfo_) + _T(".h") + xCrLf;
	headCode_ += _T("// ") + xCrLf; 
	headCode_ += GetGenerationTimeStamp();
}

void CCppClassMapGenerator::Head_generateIfDefBegin()
{
	headCode_ += _T("#if !defined(") + DefineOf(GetClassName()) + GetCardinalityPostfix(classInfo_) + _T(")") + xCrLf;
	headCode_ += _T("#define ") + DefineOf(GetClassName()) + GetCardinalityPostfix(classInfo_) + xCrLf;
	headCode_ += xCrLf;
}

void CCppClassMapGenerator::Head_generateIncludeSection()
{
	headCode_ += _T("#include <map>") + xCrLf;
	headCode_ += _T("#include \"XmlSerializable.h\"") + xCrLf;
	
	// include contained class header
	//
	headCode_ += _T("#include \"") + GetClassName(classInfo_->GetName()) + _T(".h\"") + xCrLf;
	headCode_ += xCrLf;

	headCode_ += xCrLf;
}

void CCppClassMapGenerator::Head_generateForwardDecl()
{
}

void CCppClassMapGenerator::Head_generateClassBegin()
{
	headCode_ += _T("class AFX_EXT_CLASS ") + GetClassName() + GetCardinalityPostfix(classInfo_) + _T(": public CXmlSerializable") + xCrLf;
	headCode_ += _T("{") + xCrLf;
}

void CCppClassMapGenerator::Head_generateConstructor()
{
	headCode_ += _T("public:") + xCrLf;
	headCode_ += xTab + GetClassName() + GetCardinalityPostfix(classInfo_) + _T("();") + xCrLf;
	headCode_ += xTab + GetClassName() + GetCardinalityPostfix(classInfo_) + _T("(const ") + GetClassName() + GetCardinalityPostfix(classInfo_) + _T("& copy);") + xCrLf;
}

void CCppClassMapGenerator::Head_generateDestructor()
{
	headCode_ += xTab + _T("virtual ~") + GetClassName() + GetCardinalityPostfix(classInfo_) + _T("();") + xCrLf + xCrLf;
}

void CCppClassMapGenerator::Head_generateMethods()
{
	CXmlBaseElement* sortKeyMember;
	cmString keyParam;

	sortKeyMember = classInfo_->GetMember(classInfo_->GetCardinalityInfo()->GetMapSortKey());
	if (sortKeyMember == NULL)
		return;

	if (sortKeyMember->GetDataType() == enDataType_String)
		keyParam = _T("const ") + TypeOf(sortKeyMember->GetDataType()) + _T("& key");
	else
		keyParam = TypeOf(sortKeyMember->GetDataType()) + _T(" key");

	headCode_ += xTab + _T("// utils") + xCrLf;
	headCode_ += xTab + _T("//") + xCrLf;
	headCode_ += _T("public:") + xCrLf;
	headCode_ += xTab + _T("void operator=(const ") + GetClassName() + GetCardinalityPostfix(classInfo_) + _T("& copy);") + xCrLf + xCrLf;
	headCode_ += xTab + _T("void SetDefaults();")  + xCrLf;
	headCode_ += xTab + _T("void Clear();")  + xCrLf;
	headCode_ += xCrLf;
	headCode_ += xTab + _T("// map navigation") + xCrLf;
	headCode_ += xTab + _T("//") + xCrLf;
	headCode_ += _T("public:") + xCrLf;
	headCode_ += xTab + _T("bool MoveFirst();")  + xCrLf;
	headCode_ += xTab + _T("bool MoveNext();")  + xCrLf;
	headCode_ += xTab + _T("bool GetPair(") + TypeOf(sortKeyMember->GetDataType()) + _T("& key, ") + GetClassName() + _T("** ") + GetCamelCase(classInfo_->GetName()) + _T(");")  + xCrLf;
	headCode_ += xCrLf;

	headCode_ += xTab + _T("virtual cmString GetXmlNodeName(){return _T(\"") + classInfo_->GetName() + GetCardinalityPostfix(classInfo_) + _T("\");}") + xCrLf;
	headCode_ += xCrLf;
	headCode_ += xTab + _T("// access methods") + xCrLf;
	headCode_ += xTab + _T("//") + xCrLf;
	headCode_ += xTab + _T("int GetSize() const;") + xCrLf;
	
	//headCode_ += xTab + "const " + GetClassName() + "& operator[] (" + keyParam + ") const;" + xCrLf;
	headCode_ += xTab + GetClassName() + _T("& operator[] (") + keyParam + _T(");") + xCrLf;
	headCode_ += xTab + _T("void Insert(const ") + GetClassName() + _T("& ") + GetCamelCase(classInfo_->GetName()) + _T(");") + xCrLf;
	headCode_ += xTab + _T("void Delete(") + keyParam + _T(");") + xCrLf;
	headCode_ += xTab + _T("bool Find(") + keyParam + _T(", ") + GetClassName() + _T("** ") + GetCamelCase(classInfo_->GetName()) + _T(");") + xCrLf;
	headCode_ += xTab + _T("void ReplaceKey(const cmString& currentKey, const cmString& newKey);") + xCrLf;
	headCode_ += xCrLf;

	headCode_ += _T("protected:") + xCrLf;
	headCode_ += xTab + _T("void Copy(const ") + GetClassName() + GetCardinalityPostfix(classInfo_) + _T("& copy);")  + xCrLf;
	headCode_ += xCrLf;
}

void CCppClassMapGenerator::Head_generateSerialization()
{
	headCode_ += xTab + _T("// serialization") + xCrLf;
	headCode_ += xTab + _T("//") + xCrLf;
	headCode_ += xTab + _T("public:") + xCrLf;
	headCode_ += xTab + _T("virtual bool BuildFromXml(IXMLDOMNode* node);") + xCrLf;
	headCode_ += xTab + _T("virtual bool AppendToDOMDocument(IXMLDOMDocument2* xmlDoc, IXMLDOMElement* parentElement);") + xCrLf;
	headCode_ += xCrLf;
}

void CCppClassMapGenerator::Head_generateMembers()
{
	CXmlBaseElement* sortKeyMember;
	
	sortKeyMember = classInfo_->GetMember(classInfo_->GetCardinalityInfo()->GetMapSortKey());
	if (sortKeyMember == NULL)
		return;

	headCode_ += xTab + _T("// inner members") + xCrLf;
	headCode_ += xTab + _T("//") + xCrLf;
	headCode_ += _T("protected:") + xCrLf;

	headCode_ += xTab + _T("map<") + TypeOf(sortKeyMember->GetDataType()) + _T(", ")  + GetClassName() + _T("> ") + GetCamelCase(classInfo_->GetName()+ GetCardinalityPostfix(classInfo_))  + _T("_;") + xCrLf;
	headCode_ += xTab + _T("map<") + TypeOf(sortKeyMember->GetDataType()) + _T(", ")  + GetClassName() + _T(">::iterator it_;") + xCrLf;
}

void CCppClassMapGenerator::Head_generateClassEnd()
{
	headCode_ += xCrLf;
	headCode_ += _T("};") + xCrLf;
	headCode_ += xCrLf;
}

void CCppClassMapGenerator::Head_generateIfDefEnd()
{
	headCode_ += _T("#endif //!defined(") + DefineOf(GetClassName() + GetCardinalityPostfix(classInfo_)) + _T(")") + xCrLf + xCrLf;
}

void CCppClassMapGenerator::GenerateImplementation()
{
	cmString fileName;
	cmString pathName;

	Impl_generateHeader();
	Impl_generateIncludeSection();
	
	Impl_generateConstructor();
	Impl_generateDestructor();
	Impl_generateMethods();
	Impl_generateSerialization();

	pathName = BuildGeneratedSourcePath() + _T("src\\");
	fileName = GetClassName() + GetCardinalityPostfix(classInfo_) +  _T(".cpp");
	SaveFile(pathName + fileName, implCode_);

	cppGeneratedFiles_[fileName] = pathName + fileName;
}

void CCppClassMapGenerator::Impl_generateHeader()
{
	implCode_ += _T("// ") + GetClassName() + GetCardinalityPostfix(classInfo_) + _T(".cpp") + xCrLf;
	implCode_ += _T("// ") + xCrLf; 
	implCode_ += GetGenerationTimeStamp();
	implCode_ += _T("#pragma warning(disable:4786)") + xCrLf;
	implCode_ += xCrLf;
}

void CCppClassMapGenerator::Impl_generateIncludeSection()
{
	implCode_ += _T("#include \"stdafx.h\"") + xCrLf;
	implCode_ += _T("#include \"") + GetClassName() + GetCardinalityPostfix(classInfo_) + _T(".h\"") + xCrLf;

	ClassMemberMap::iterator it;
	ClassMemberMap* members;
	CXmlBaseElement* member;
	cmString name;

	members = classInfo_->GetMembers();
	for(it = members->begin(); it != members->end(); it++) {
		member = it->second;
		if (member->GetDataType() == enDataType_Class) {
			CXmlClassInfo* classInfo;

			classInfo = dynamic_cast<CXmlClassInfo*>(member);
			if (classInfo->GetDefinitionInheritance())
				classInfo = dynamic_cast<CXmlClassInfo*>(rootClassInfo_->GetMemberById(classInfo->GetInherithClassId()));

			name = classInfo->GetName();
			implCode_ += _T("#include \"") + GetClassName(name) + _T(".h\"") + xCrLf;
		}
	}

	implCode_ +=  xCrLf;
}

void CCppClassMapGenerator::Impl_generateConstructor()
{
	cmString p;

	p = GetCardinalityPostfix(classInfo_);

	// default constructor
	//
	implCode_ += GetClassName() + p + _T("::") + GetClassName() + p + _T("()") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("SetDefaults();") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;

	// copy constructor
	//
	implCode_ += GetClassName() + p + _T("::");
	implCode_ += GetClassName() + p;
	implCode_ += _T("(const ") + GetClassName()  + p + _T("& ");
	implCode_ += GetCamelCase(classInfo_->GetName())  + p + _T(")") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("Copy(") + GetCamelCase(classInfo_->GetName()) + p + _T(");") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;
}

void CCppClassMapGenerator::Impl_generateDestructor()
{
	cmString p;

	p = GetCardinalityPostfix(classInfo_);

	implCode_ += GetClassName() + p + _T("::~") + GetClassName() + p + _T("()") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("Clear();") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;
}

void CCppClassMapGenerator::Impl_generateMethods()
{
	CXmlBaseElement* sortKeyMember;
	cmString p;
	cmString keyParam;

	sortKeyMember = classInfo_->GetMember(classInfo_->GetCardinalityInfo()->GetMapSortKey());
	if (sortKeyMember == NULL)
		return;

	if (sortKeyMember->GetDataType() == enDataType_String)
		keyParam = _T("const ") + TypeOf(sortKeyMember->GetDataType()) + _T("& key");
	else
		keyParam = TypeOf(sortKeyMember->GetDataType()) + _T(" key");

	p = GetCardinalityPostfix(classInfo_);
	// operator =
	//
	implCode_ += _T("void ") +  GetClassName() + p + _T("::operator=(const ") + GetClassName() + p + _T("& ") + GetCamelCase(classInfo_->GetName()) + p + _T(")") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("Copy(") + GetCamelCase(classInfo_->GetName()) + p + _T(");") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;

	// Copy
	//
	cmString mapName;
	cmString paramName;

	mapName = GetCamelCase(classInfo_->GetName()) + p;
	paramName = GetCamelCase(classInfo_->GetName()) + p;
	implCode_ += _T("void ") + GetClassName() + p + _T("::Copy(const ") + GetClassName() + p + _T("& ") + paramName + _T(")")  + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("Clear();") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("map<") + TypeOf(sortKeyMember->GetDataType()) + _T(", ")  + GetClassName() + _T(">::const_iterator it;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("for (it = ") + paramName + _T(".") + mapName + _T("_.begin(); it != ") + paramName + _T(".") + mapName + _T("_.end(); it++)") + xCrLf;
	implCode_ += xTab + xTab + mapName + _T("_[it->first] = it->second;") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;

	// SetDefaults
	//
	implCode_ += _T("void ") + GetClassName() + p + _T("::SetDefaults()")  + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("Clear();") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;

	// SetDefaults
	//
	implCode_ += _T("void ") + GetClassName() + p + _T("::Clear()")  + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + mapName + _T("_.clear();") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;

	// GetSize
	//
	implCode_ += _T("int ") + GetClassName() + p + _T("::GetSize() const")  + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("return ") + mapName + _T("_.size();") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;

	// operator []
	//
	////// 
	////// implCode_ += "const " + GetClassName() + "& " + GetClassName() + p +"::operator[] (" + keyParam + ") const" + xCrLf;
	////// implCode_ += "{" + xCrLf;
	////// implCode_ += xTab + "return " + mapName + "_[key];" + xCrLf;
	////// implCode_ += "}" + xCrLf;
	////// implCode_ += xCrLf;
	

	// operator []
	//
	implCode_ += GetClassName() + _T("& ") + GetClassName() + p + _T("::operator[] (") + keyParam + _T(")") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("return ") + mapName + _T("_[key];") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;

	// Insert
	//
	paramName = GetCamelCase(classInfo_->GetName());
	implCode_ += _T("void ") + GetClassName() + p + _T("::Insert(const ") + GetClassName() + _T("& ") + paramName + _T(")") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + mapName + _T("_[") + paramName + _T(".Get") + sortKeyMember->GetName() + _T("()] = ") + paramName + _T(";") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;

	// Delete
	//
	implCode_ += _T("void ") + GetClassName() + p + _T("::Delete(") + keyParam + _T(")") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + mapName + _T("_.erase(key);") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;

	// Find
	//
	implCode_ += _T("bool ") + GetClassName() + p + _T("::Find(") + keyParam + _T(", ") + GetClassName() + _T("** ") + paramName + _T(")") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("map<") + TypeOf(sortKeyMember->GetDataType()) + _T(", ")  + GetClassName() + _T(">::iterator it;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("it = ") + mapName + _T("_.find(key);") + xCrLf;
	implCode_ += xTab + _T("if (it != ") + mapName + _T("_.end())") + xCrLf;
	implCode_ += xTab + xTab + _T("*") + paramName + _T(" = &(it->second);") + xCrLf;
	implCode_ += xTab + _T("else") + xCrLf;
	implCode_ += xTab + xTab + _T("*") + paramName + _T(" = NULL;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("return (it != ") + mapName + _T("_.end());") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;

	// ReplaceKey
	//
	implCode_ += _T("void ") + GetClassName() + p + _T("::ReplaceKey(const cmString& currentKey, const cmString& newKey)") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("map<") + TypeOf(sortKeyMember->GetDataType()) + _T(", ")  + GetClassName() + _T(">::iterator it;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("it = ") + mapName + _T("_.find(newKey);") + xCrLf;
	implCode_ += xTab + _T("if (it != ") + mapName + _T("_.end())") + xCrLf;
	implCode_ += xTab + xTab + _T("return;") + xCrLf;
	implCode_ += xCrLf;	
	implCode_ += xTab + _T("it = ") + mapName + _T("_.find(currentKey);") + xCrLf;
	implCode_ += xTab + _T("if (it != ") + mapName + _T("_.end()) {") + xCrLf;
	implCode_ += xTab + xTab + GetClassName() + _T(" tmp;") + xCrLf;
	implCode_ += xTab + xTab + _T("tmp = it->second;") + xCrLf;
	implCode_ += xTab + xTab + _T("tmp.Set") + sortKeyMember->GetName() + _T("(newKey);") + xCrLf;
	implCode_ += xTab + xTab + mapName + _T("_.erase(it);") + xCrLf;
	implCode_ += xTab + xTab + mapName + _T("_[newKey] = tmp;") + xCrLf;
	implCode_ += xTab + _T("}") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;

	// MoveFirst
	//
	implCode_ += _T("bool ") + GetClassName() + p + _T("::MoveFirst()") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("it_ = ") + mapName + _T("_.begin();") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("return ") + mapName + _T("_.size() != 0;") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;

	// MoveNext
	//
	implCode_ += _T("bool ") + GetClassName() + p + _T("::MoveNext()")  + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("it_++;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("return it_ != ") + mapName + _T("_.end();") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;
	
	// GetPair
	//
	implCode_ += _T("bool ") + GetClassName() + p + _T("::GetPair(") + TypeOf(sortKeyMember->GetDataType()) + _T("& key, ") + GetClassName() + _T("** ") + GetCamelCase(classInfo_->GetName()) + _T(")")  + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("if (it_ != ") + mapName + _T("_.end()) {") + xCrLf;
	implCode_ += xTab + xTab + _T("key = it_->first;") + xCrLf;
	implCode_ += xTab + xTab + _T("*") + GetCamelCase(classInfo_->GetName()) + _T(" = &(it_->second);") + xCrLf;
	implCode_ += xTab + xTab + _T("return true;") + xCrLf;
	implCode_ += xTab + _T("}") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("*") + GetCamelCase(classInfo_->GetName()) + _T(" = NULL;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("return false;") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;

}

void CCppClassMapGenerator::Impl_generateSerialization()
{
	ClassMemberMap::iterator it;
	CXmlBaseElement* member;
	cmString mapName;
	cmString sortKey;
	cmString p;

	p = GetCardinalityPostfix(classInfo_);
	mapName = GetCamelCase(classInfo_->GetName()) + p;
	sortKey = _T("newChildElement.Get") + classInfo_->GetCardinalityInfo()->GetMapSortKey() + _T("()");
	member = classInfo_->GetMember(classInfo_->GetCardinalityInfo()->GetMapSortKey());

	//////////////////////////////////////////////////////////////////////
	// BuildFromXml
	//
	implCode_ += _T("bool ") + GetClassName() + p + _T("::BuildFromXml(IXMLDOMNode* node)") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("USES_CONVERSION;") + xCrLf + xCrLf;

	implCode_ += xTab + _T("IXMLDOMNode* childNode;") + xCrLf;
    implCode_ += xTab + _T("IXMLDOMNodeList* children;") + xCrLf;
	implCode_ += xTab + _T("HRESULT hr;") + xCrLf;
	implCode_ += xTab + _T("long size;") + xCrLf;
	implCode_ += xTab + _T("CComBSTR nodeName;") + xCrLf;
	implCode_ += xTab + GetClassName() + _T(" newChildElement;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("SetDefaults();") + xCrLf;
	implCode_ += xTab + xCrLf;

	implCode_ += xTab + _T("hr = node->get_childNodes(&children);") + xCrLf;
	implCode_ += xTab + _T("hr = children->get_length(&size);") + xCrLf;

	implCode_ += xTab + _T("for (long i = 0; i < size; i++) {") + xCrLf;
	implCode_ += xTab + xTab + _T("hr = children->get_item(i, &childNode);") + xCrLf;
	
	implCode_ += xTab + xTab + _T("hr = childNode->get_nodeName(&nodeName);") + xCrLf;
	//implCode_ += xTab + xTab + _T("if (nodeName == newChildElement.GetXmlNodeName()) {") + xCrLf;
	implCode_ += xTab + xTab + _T("if (newChildElement.GetXmlNodeName().CompareNoCase(W2T((BSTR)nodeName)) == 0) {") + xCrLf;
	implCode_ += xTab + xTab + xTab + _T("newChildElement.BuildFromXml(childNode);") + xCrLf;
	//implCode_ += xTab + xTab + xTab + mapName + "_[" + sortKey + "] = newChildElement;" + xCrLf;
	implCode_ += xTab + xTab + xTab + mapName + _T("_.insert(make_pair<cmString, ") + GetClassName() + _T(">(") + sortKey + _T(", newChildElement));") + xCrLf;
	implCode_ += xTab + xTab + _T("}") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("}") + xCrLf + xCrLf;

	implCode_ += xTab + _T("return true;") + xCrLf;

	implCode_ += _T("}") + xCrLf + xCrLf;

	//////////////////////////////////////////////////////////////////////
	// AppendToDOMDocument
	//
	implCode_ += _T("bool ") + GetClassName() + p + _T("::AppendToDOMDocument(IXMLDOMDocument2* xmlDoc, IXMLDOMElement* parentElement)") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("map<") + TypeOf(member->GetDataType()) + _T(", ")  + GetClassName() + _T(">::iterator it;") + xCrLf;
    	
	if (classInfo_->GetCardinalityInfo()->GetUseContainerNode()) {
		implCode_ += xTab + _T("IXMLDOMElement* newElement;") + xCrLf;
		implCode_ += xTab + _T("HRESULT hr;") + xCrLf;
		implCode_ += xCrLf;
		implCode_ += xTab + _T("hr = xmlDoc->createElement(CComBSTR((const TCHAR*)GetXmlNodeName()), &newElement);") + xCrLf;
		implCode_ += xTab + _T("if (FAILED(hr))") + xCrLf;
		implCode_ += xTab + xTab + _T("return false;") + xCrLf;
		implCode_ += xCrLf;
		implCode_ += xTab + _T("for (it = ") + mapName + _T("_.begin(); it != ") + mapName + _T("_.end(); it++)") + xCrLf;
		implCode_ += xTab + xTab + _T("it->second.AppendToDOMDocument(xmlDoc, newElement);") + xCrLf;
		implCode_ += xCrLf;
		implCode_ += xTab + _T("if (parentElement)") + xCrLf;
		implCode_ += xTab + xTab + _T("hr = parentElement->appendChild(newElement, NULL);") + xCrLf;
		implCode_ += xTab + _T("else") + xCrLf;
		implCode_ += xTab + xTab + _T("hr = xmlDoc->appendChild(newElement, NULL);") + xCrLf;
		implCode_ += xCrLf;
	} else {
		implCode_ += xCrLf;
		implCode_ += xTab + _T("for (it = ") + mapName + _T("_.begin(); it != ") + mapName + _T("_.end(); it++)") + xCrLf;
		implCode_ += xTab + xTab + _T("it->second.AppendToDOMDocument(xmlDoc, parentElement);") + xCrLf;
		implCode_ += xCrLf;
	}
	//implCode_ += xTab + _T("newOutNode->Release();") + xCrLf;
	//implCode_ += xCrLf;
	implCode_ += xTab + _T("return true;") + xCrLf;
	implCode_ += _T("}") + xCrLf + xCrLf;

	
}


  ****/