// CAtlClassGenerator.cpp
//
#include "stdafx.h"
#include "AtlClassGenerator.h"
#include "XmlProjectSettings.h"
#include "XmlClassInfo.h"
#include "XmlMemberInfo.h"
#include "XmlProject.h"
#include "XmlMemberValidation_StaticEnumItem.h"

CAtlClassGenerator::CAtlClassGenerator()
{}

CAtlClassGenerator::~CAtlClassGenerator()
{}

void CAtlClassGenerator::Generate()
{
	// generate header file
	//
	GenerateHeader();
	
	// generate implementation file
	//
	GenerateImplementation();
}
	
void CAtlClassGenerator::GenerateHeader()
{
	cmString fileName;
	cmString pathName;
	
	Head_generateHeader();
	Head_generateIfDefBegin();
	Head_generateIncludeSection();
	Head_generateForwardDecl();
	Head_generateClassBegin();
	Head_generateConstructor();
	Head_generateDestructor();
	Head_generateUtils();
	Head_generateSerialization();
	Head_generateGetSet();
	Head_generateMembers();
	Head_generateClassEnd();
	Head_generateIfDefEnd();

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

	hGeneratedFiles_[fileName] = pathName + fileName;
}

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

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

void CAtlClassGenerator::Head_generateIncludeSection()
{
	headCode_ += _T("#include \"XmlSerializable.h\"") + xCrLf;
	headCode_ += _T("#include \"ProjectConfigAtl.h\"") + xCrLf;
	headCode_ += _T("#include \"resource.h\"") + xCrLf;
	headCode_ += _T("#include \"cmString.h\"") + xCrLf;

	// include children header files
	//
	ClassMemberMap::iterator it;
	ClassMemberMap* members;
	CXmlBaseElement* member;
	CXmlClassInfo* classInfo;
	members = classInfo_->GetMembers();
	for(it = members->begin(); it != members->end(); it++) {
		member = it->second;
	
		if (member->GetDataType() == enDataType_Class) {
			cmString name;
			cmString p;

			classInfo = dynamic_cast<CXmlClassInfo*>(member);
			if (!classInfo->GetDefinitionInheritance()) {
				name = member->GetName();
				p = GetCardinalityPostfix(member);
			} else {
				CXmlClassInfo* inheritClassInfo;

				inheritClassInfo = dynamic_cast<CXmlClassInfo*>(rootClassInfo_->GetMemberById(classInfo->GetInherithClassId()));
				name = inheritClassInfo->GetName();
				p = GetCardinalityPostfix(inheritClassInfo);
			}

			headCode_ += _T("#include \"") + GetClassName(name) + p + _T(".h\"");
			headCode_ += xCrLf;
		}
	}

	headCode_ += xCrLf;
}

void CAtlClassGenerator::Head_generateForwardDecl()
{
	/*ClassMemberMap::iterator it;
	ClassMemberMap* members;
	CXmlBaseElement* member;

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

			classInfo = dynamic_cast<CXmlClassInfo*>(member);
			if (classInfo->GetDefinitionInheritance()) {
				inheritClassInfo = dynamic_cast<CXmlClassInfo*>(rootClassInfo_->GetMemberById(classInfo->GetInherithClassId()));
				name = inheritClassInfo->GetName();
			} else {
				name = classInfo->GetName();
			}
			headCode_ += "class I" + GetClassName(name) + ";" + xCrLf;
		}
	}

	headCode_ += xCrLf;*/
}

void CAtlClassGenerator::Head_generateClassBegin()
{
	cmString prefix;
	cmString name;

	prefix = project_->GetProjectSettings()->GetAtlSettings()->GetClassPrefix();
	name = GetClassName();
	
	headCode_ += _T("/////////////////////////////////////////////////////////////////////////////") + xCrLf;
	headCode_ += _T("// ") + name + xCrLf;
	headCode_ += _T("class ATL_NO_VTABLE ") + name + _T(":") + xCrLf; 
	headCode_ += _T("public CComObjectRootEx<CComSingleThreadModel>,") + xCrLf;
	headCode_ += _T("public CComCoClass<") + name + _T(", &CLSID_") + classInfo_->GetName() + _T(">,") + xCrLf;
	headCode_ += _T("public IDispatchImpl<I") + name + _T(", &IID_I") + name + _T(", &LIBID_") + ToUpperCase(prefix) + _T("Lib>,") + xCrLf;
	headCode_ += _T("public CXmlSerializable") + xCrLf;
	headCode_ += _T("{") + xCrLf;
	headCode_ += xCrLf;
	headCode_ += _T("public:") + xCrLf;
	headCode_ += xTab + _T("DECLARE_REGISTRY_RESOURCEID(IDR_") + ToUpperCase(classInfo_->GetName()) + _T(")") + xCrLf;
	headCode_ += xTab + _T("DECLARE_NOT_AGGREGATABLE(") + name + _T(")") + xCrLf;
	headCode_ += xCrLf;
	headCode_ += xTab + _T("DECLARE_PROTECT_FINAL_CONSTRUCT()") + xCrLf;
	headCode_ += xCrLf;
	headCode_ += xTab + _T("BEGIN_COM_MAP(") + name + _T(")") + xCrLf;
	headCode_ += xTab + xTab + _T("COM_INTERFACE_ENTRY(I") + name + _T(")") + xCrLf;
	headCode_ += xTab + xTab + _T("COM_INTERFACE_ENTRY(IDispatch)") + xCrLf;
	headCode_ += xTab + _T("END_COM_MAP()") + xCrLf;
	headCode_ += xCrLf;
}

void CAtlClassGenerator::Head_generateConstructor()
{
	headCode_ += _T("public:") + xCrLf;
	headCode_ += xTab + GetClassName() + _T("();") + xCrLf;
}

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

void CAtlClassGenerator::Head_generateUtils()
{
	headCode_ += xTab + _T("// utils") + xCrLf;
	headCode_ += xTab + _T("//") + xCrLf;
	headCode_ += _T("public:") + xCrLf;
	headCode_ += xTab + _T("void SetDefaults();")  + xCrLf;
	headCode_ += xTab + _T("void Clear();")  + xCrLf;
	headCode_ += xTab + _T("virtual cmString GetXmlNodeName(){return xmlNodeName_;}") + xCrLf;
	headCode_ += xTab + _T("static cmString xmlNodeName_;") + xCrLf;
	headCode_ += xCrLf;
}

void CAtlClassGenerator::Head_generateGetSet()
{
	ClassMemberMap::iterator it;
	ClassMemberMap* members;
	CXmlBaseElement* member;
	CXmlMemberInfo* memberInfo;
	cmString p;
	cmString type;
	cmString methodName;
	cmString n;

	members = classInfo_->GetMembers();
	for(it = members->begin(); it != members->end(); it++) {
		member = it->second;
			
		if (member->GetDataType() == enDataType_Class) {
			CXmlClassInfo* classInfo;
			CXmlClassInfo* tmpClassInfo;
	
			classInfo = dynamic_cast<CXmlClassInfo*>(member);
			if (classInfo->GetDefinitionInheritance())
				tmpClassInfo = dynamic_cast<CXmlClassInfo*>(rootClassInfo_->GetMemberById(classInfo->GetInherithClassId()));
			else
				tmpClassInfo = classInfo;
			
			n = tmpClassInfo->GetName();
			p = GetCardinalityPostfix(tmpClassInfo);

			type = _T("I") + GetClassName(n) + p + _T("*");
			methodName = n + p;
		} else {

			memberInfo = dynamic_cast<CXmlMemberInfo*>(member);
			
			methodName = member->GetName();
			if (memberInfo->GetValidationInfo()->GetValidationMode() == enValidationMode_StaticEnum) {
				type = OleTypeOf(member->GetDataType());	
				headCode_ += xTab + _T("STDMETHOD(get_") + methodName + _T("_Value)(/*[out, retval]*/ ") + type + _T("* pVal);") + xCrLf;
				
				type = _T("en") + memberInfo->GetName();
			} else
				type = OleTypeOf(member->GetDataType());

			
		}

		headCode_ += xTab + _T("STDMETHOD(get_") + methodName + _T(")(/*[out, retval]*/ ") + type + _T("* pVal);") + xCrLf;
		headCode_ += xTab + _T("STDMETHOD(put_") + methodName + _T(")(/*[in]*/ ") + type + _T(" newVal);") + xCrLf;
		headCode_ += xCrLf;
	}
}

void CAtlClassGenerator::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;
	headCode_ += xTab + _T("// I") + GetClassName() + xCrLf;
	headCode_ += xTab + _T("//") + xCrLf;
	headCode_ += xTab + _T("public:") + xCrLf;
	headCode_ += xTab + _T("STDMETHOD(CleanUp)();") + xCrLf;
	headCode_ += xTab + _T("STDMETHOD(RestoreDefaults)();") + xCrLf;
	headCode_ += xTab + _T("STDMETHOD(Save)(/*[in]*/ BSTR fileName, /*[out, retval]*/ VARIANT_BOOL* retval);") + xCrLf;
	headCode_ += xTab + _T("STDMETHOD(Load)(/*[in]*/ BSTR fileName, /*[out, retval]*/ VARIANT_BOOL* retval);") + xCrLf;
	headCode_ += xTab + _T("STDMETHOD(Copy)(/*[in]*/ I") + GetClassName() + _T("* source);")  + xCrLf;
	headCode_ += xCrLf;
}

void CAtlClassGenerator::Head_generateMembers()
{
	ClassMemberMap* members;
	ClassMemberMap::iterator it;
	CXmlBaseElement* member;
	
	headCode_ += xTab + _T("// inner members") + xCrLf;
	headCode_ += xTab + _T("//") + xCrLf;
	headCode_ += _T("protected:") + xCrLf;

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

			classInfo = dynamic_cast<CXmlClassInfo*>(member);
			if (classInfo->GetDefinitionInheritance()) {
				CXmlClassInfo* inheritClassInfo;

				inheritClassInfo = dynamic_cast<CXmlClassInfo*>(rootClassInfo_->GetMemberById(classInfo->GetInherithClassId()));
				name = inheritClassInfo->GetName();
				p = GetCardinalityPostfix(inheritClassInfo);

				classInfo = inheritClassInfo;
			} else {
				name = classInfo->GetName();
				p = GetCardinalityPostfix(member);
			}

			headCode_ += xTab + _T("CComObject<") + GetClassName(name) + p + _T(">* ");
			headCode_ += GetCamelCase(name) + p + _T("_;") + xCrLf;
		} else {
			cmString type;
			CXmlMemberInfo* memberInfo;

			memberInfo = dynamic_cast<CXmlMemberInfo*>(member);
			if (memberInfo->GetValidationInfo()->GetValidationMode() == enValidationMode_StaticEnum)
				type = _T("en") + memberInfo->GetName();
			else
				type = TypeOf(member->GetDataType());

			headCode_ += xTab + type + _T(" ") + GetCamelCase(member->GetName()) + _T("_;") + xCrLf;
		}
	}
}

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

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

void CAtlClassGenerator::GenerateImplementation()
{
	cmString fileName;
	cmString pathName;
	
	Impl_generateHeader();
	Impl_generateIncludeSection();
	
	Impl_generateConstructor();
	Impl_generateDestructor();
	Impl_generateUtils();
	Impl_generateGetSet();
	Impl_generateSerialization();

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

	cppGeneratedFiles_[fileName] = pathName + fileName;
}

void CAtlClassGenerator::Impl_generateHeader()
{
	implCode_ += _T("// ") + GetClassName() + _T(".cpp") + xCrLf;
	implCode_ += _T("// ") + xCrLf; 
	implCode_ += GetGenerationTimeStamp();
}

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

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

	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())
				implCode_ += _T("#include \"") + GetClassName(classInfo->GetName()) + _T(".h\"") + xCrLf;
		}
	}

	implCode_ +=  xCrLf;
}

void CAtlClassGenerator::Impl_generateConstructor()
{
	implCode_ += _T("cmString ") + GetClassName() + _T("::xmlNodeName_ = _T(\"") + classInfo_->GetName() + _T("\");") + xCrLf;
	implCode_ += xCrLf;

	// default constructor
	//
	implCode_ += GetClassName() + _T("::") + GetClassName() + _T("()") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	
	if (classInfo_->GetMemberCount(enDataType_Class)) {
		implCode_ += xTab + _T("HRESULT hRes;") + xCrLf;
		implCode_ += xCrLf;
	}
	
	// generate CComObject members allocation and creation
	//
	ClassMemberMap* members;
	ClassMemberMap::iterator it;
	CXmlBaseElement* member;
	
	members = classInfo_->GetMembers();
	for(it = members->begin(); it != members->end(); it++) {
		member = it->second;
	
		if (member->GetDataType() == enDataType_Class) {
			CXmlClassInfo* classInfo;
			cmString p;
			cmString n;

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

			// new
			//
//			implCode_ += xTab + GetCamelCase(n) + p + "_ = new CComObject<" + GetClassName(n) + p + ">;" + xCrLf;
			
			// createInstance
			implCode_ += xTab + _T("hRes = CComObject<") + GetClassName(n) + p + _T(">::CreateInstance(&") + GetCamelCase(n) + p + _T("_);") + xCrLf;
			implCode_ += xTab + GetCamelCase(n) + p + _T("_->AddRef();") + xCrLf;
			implCode_ += xCrLf;
		}
	}
	
	implCode_ += xTab + _T("SetDefaults();") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;
}

void CAtlClassGenerator::Impl_generateDestructor()
{
	implCode_ += GetClassName() + _T("::~") + GetClassName() + _T("()") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("CleanUp();") + xCrLf;
	implCode_ += xCrLf;

	// generate CComObject members deallocation
	//
	ClassMemberMap* members;
	ClassMemberMap::iterator it;
	CXmlBaseElement* member;
	
	members = classInfo_->GetMembers();
	for(it = members->begin(); it != members->end(); it++) {
		member = it->second;
	
		if (member->GetDataType() == enDataType_Class) {
			CXmlClassInfo* classInfo;
			cmString p;
			cmString name;

			classInfo = dynamic_cast<CXmlClassInfo*>(member);
			if (classInfo->GetDefinitionInheritance()) {
				CXmlClassInfo* inheritClassInfo;

				inheritClassInfo = dynamic_cast<CXmlClassInfo*>(rootClassInfo_->GetMemberById(classInfo->GetInherithClassId()));
				name = inheritClassInfo->GetName();
				p = GetCardinalityPostfix(inheritClassInfo);

				classInfo = inheritClassInfo;
			} else {
				name = classInfo->GetName();
				p = GetCardinalityPostfix(member);
			}
			
			// new
			//
			implCode_ += xTab + GetCamelCase(name) + p + _T("_->Release();") + xCrLf;
		}
	}

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

void CAtlClassGenerator::Impl_generateUtils()
{
	ClassMemberMap::iterator it;
	ClassMemberMap* members;
	CXmlBaseElement* member;
	CXmlClassInfo* classInfo;
	CXmlMemberInfo* memberInfo;
	cmString p;
	cmString name;

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

	// copy
	//
	
	implCode_ += _T("STDMETHODIMP ") + GetClassName() + _T("::Copy(I") + GetClassName() + _T("* source)")  + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("USES_CONVERSION;") + xCrLf;
	implCode_ += xTab + _T("CleanUp();") + xCrLf;
	implCode_ += xCrLf;

	members = classInfo_->GetMembers();
	for(it = members->begin(); it != members->end(); it++) {
		member = it->second;
		cmString tmp;

		switch (member->GetDataType()) {
			case enDataType_Class:
				classInfo = dynamic_cast<CXmlClassInfo*>(member);
				if (classInfo->GetDefinitionInheritance()) {
					classInfo = dynamic_cast<CXmlClassInfo*>(rootClassInfo_->GetMemberById(classInfo->GetInherithClassId()));
				}
				p = GetCardinalityPostfix(classInfo);
				name = classInfo->GetName();

				tmp = GetCamelCase(name) + p;
				implCode_ += xTab + _T("I") + GetClassName(name) + p + _T("* ") + tmp + _T(";") + xCrLf;
				implCode_ += xTab + _T("source->get_") + name + p + _T("(&") + tmp + _T(");") + xCrLf;
				implCode_ += xTab + tmp + _T("_->Copy(") + tmp + _T(");") + xCrLf;
				implCode_ += xTab + tmp + _T("->Release();") + xCrLf;
				implCode_ += xCrLf;
				break;

			case enDataType_String:
		
				tmp = GetCamelCase(member->GetName());
				memberInfo = dynamic_cast<CXmlMemberInfo*>(member);
				if (memberInfo->GetValidationInfo()->GetValidationMode() == enValidationMode_StaticEnum) {
					implCode_ += xTab + _T("en") + memberInfo->GetName() + _T(" ") + tmp + _T(";") + xCrLf;
					implCode_ += xTab + _T("source->get_") + member->GetName() + _T("(&") + tmp + _T(");") + xCrLf;
					implCode_ += xTab + GetCamelCase(member->GetName()) + _T("_ = ") + tmp + _T(";") + xCrLf;
					implCode_ += xCrLf;
				} else {
					implCode_ += xTab + _T("CComBSTR ") + tmp + _T(";") + xCrLf;
					implCode_ += xTab + _T("source->get_") + member->GetName() + _T("(&") + tmp + _T(");") + xCrLf;
					implCode_ += xTab + GetCamelCase(member->GetName()) + _T("_ = W2T(") + tmp + _T(");") + xCrLf;
					implCode_ += xCrLf;
				}
				break;

			default:
				{
					cmString type;

					memberInfo = dynamic_cast<CXmlMemberInfo*>(member);
					if (memberInfo->GetValidationInfo()->GetValidationMode() == enValidationMode_StaticEnum)
						type = _T("en") + memberInfo->GetName();
					else
						type = OleTypeOf(member->GetDataType());
					
					tmp = GetCamelCase(member->GetName());

					implCode_ += xTab + type + _T(" ") + tmp + _T(";") + xCrLf;
					implCode_ += xTab + _T("source->get_") + member->GetName() + _T("(&") + tmp + _T(");") + xCrLf;
					implCode_ += xTab + GetCamelCase(member->GetName()) + _T("_ = ") + tmp + _T(";") + xCrLf;
					implCode_ += xCrLf;
				}
		}
	}
	implCode_ += xTab + _T("return S_OK;") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;

	// SetDefaults
	//
	implCode_ += _T("STDMETHODIMP ") + GetClassName() + _T("::RestoreDefaults()")  + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("CleanUp();") + xCrLf;
	
	implCode_ += xTab + _T("SetDefaults();") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("return S_OK;") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;

	// SetDefaults
	//
	implCode_ += _T("STDMETHODIMP ") + GetClassName() + _T("::CleanUp()")  + xCrLf;
	implCode_ += _T("{") + xCrLf;
	for(it = members->begin(); it != members->end(); it++) {
		member = it->second;
	
		switch (member->GetDataType()) {
			case enDataType_Class:
				classInfo = dynamic_cast<CXmlClassInfo*>(member);
				if (classInfo->GetDefinitionInheritance()) {
					classInfo = dynamic_cast<CXmlClassInfo*>(rootClassInfo_->GetMemberById(classInfo->GetInherithClassId()));
				}
				p = GetCardinalityPostfix(classInfo);
				name = classInfo->GetName();
				implCode_ += xTab + GetCamelCase(name) + p + _T("_->CleanUp();") + xCrLf;
				break;

			case enDataType_Long:
			case enDataType_Double:
			case enDataType_Boolean:
			case enDataType_String:
				break;
		}
			
	}
	implCode_ += xCrLf;
	implCode_ += xTab + _T("return S_OK;") + xCrLf;
	implCode_ += _T("}") + xCrLf + xCrLf;
	implCode_ += xCrLf;

	// SetDefaults
	//
	implCode_ += _T("void ") + GetClassName() + _T("::SetDefaults()")  + xCrLf;
	implCode_ += _T("{") + xCrLf;
	members = classInfo_->GetMembers();
	for(it = members->begin(); it != members->end(); it++) {
		CXmlMemberInfo* memberInfo;

		member = it->second;
		memberInfo = dynamic_cast<CXmlMemberInfo*>(member);
		switch (member->GetDataType()) {
			case enDataType_Class:
				classInfo = dynamic_cast<CXmlClassInfo*>(member);
				if (classInfo->GetDefinitionInheritance()) {
					classInfo = dynamic_cast<CXmlClassInfo*>(rootClassInfo_->GetMemberById(classInfo->GetInherithClassId()));
				}
				p = GetCardinalityPostfix(classInfo);
				name = classInfo->GetName();
				implCode_ += xTab + GetCamelCase(name) + p + _T("_->RestoreDefaults();") + xCrLf;
				break;

			case enDataType_Long:
			case enDataType_Double:
				if (memberInfo->GetValidationInfo()->GetValidationMode() == enValidationMode_StaticEnum)
					implCode_ += xTab + GetCamelCase(member->GetName()) + _T("_ = (en") + member->GetName() + _T(")0;") + xCrLf;
				else
					implCode_ += xTab + GetCamelCase(member->GetName()) + _T("_ = 0;") + xCrLf;
				break;

			case enDataType_Boolean:
				implCode_ += xTab + GetCamelCase(member->GetName()) + _T("_ = VARIANT_FALSE;") + xCrLf;
				break;

			case enDataType_String:
				if (memberInfo->GetValidationInfo()->GetValidationMode() == enValidationMode_StaticEnum) {
					CXmlMemberValidation_StaticEnumItem* item;
					StaticEnumItems* items;

					items = memberInfo->GetValidationInfo()->GetStaticEnum()->GetItems();
					
					// if enum list contains a set of values set default to the first value
					//
					if (items->size()) {
						item = (*items)[0];
						
						implCode_ += xTab + GetCamelCase(member->GetName()) + _T("_ = en") + member->GetName() + _T("_") + item->GetItemName() + _T(";") + xCrLf;
					}

					
				} else {
					implCode_ += xTab + GetCamelCase(member->GetName()) + _T("_ = _T(\"\");") + xCrLf;
				}
				
		}
			
	}

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

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

void CAtlClassGenerator::Impl_generateGetSet()
{
	ClassMemberMap::iterator it;
	ClassMemberMap* members;
	CXmlBaseElement* member;
	CXmlMemberInfo* memberInfo;
	cmString type;
	cmString name;
	cmString p;
	
	members = classInfo_->GetMembers();
	for(it = members->begin(); it != members->end(); it++) {
		member = it->second;
	
		switch (member->GetDataType()) {
			case enDataType_Class: 
				CXmlClassInfo* classInfo;
				CXmlClassInfo* inheritClassInfo;
				
				classInfo = dynamic_cast<CXmlClassInfo*>(member);
				if (classInfo->GetDefinitionInheritance()) {
					inheritClassInfo = dynamic_cast<CXmlClassInfo*>(rootClassInfo_->GetMemberById(classInfo->GetInherithClassId()));
					name = inheritClassInfo->GetName();
					p = GetCardinalityPostfix(inheritClassInfo);
				} else {
					name = classInfo->GetName();
					p = GetCardinalityPostfix(member);
				}

				type = GetClassName(name) + p;	
				
				implCode_ += _T("STDMETHODIMP ") + GetClassName() + _T("::get_") + name + p + _T("(I") + type + _T("** ") + GetCamelCase(name) + p + _T(")") + xCrLf;
				implCode_ += _T("{") + xCrLf;
				implCode_ += xTab + _T("return ") + GetCamelCase(name) + p + _T("_->QueryInterface(IID_I") + GetClassName(name) + p + _T(", (void**)") + GetCamelCase(name) + p + _T(");") + xCrLf;
				implCode_ += _T("}") + xCrLf;
				implCode_ += xCrLf;

				implCode_ += _T("STDMETHODIMP ") + GetClassName() + _T("::put_") + name + p + _T("(I") + type + _T("* ") + GetCamelCase(name) + p + _T(")") + xCrLf;
				implCode_ += _T("{") + xCrLf;
				implCode_ += xTab + GetCamelCase(name) + p + _T("_->Copy(") + GetCamelCase(name) + p + _T(");") + xCrLf;
				implCode_ += xTab + _T("return S_OK;") + xCrLf;
				implCode_ += _T("}") + xCrLf;
				implCode_ += xCrLf;
				break;

			case enDataType_String:
				memberInfo = dynamic_cast<CXmlMemberInfo*>(member);
				if (memberInfo->GetValidationInfo()->GetValidationMode() == enValidationMode_StaticEnum) {
					CXmlMemberValidation_StaticEnumItem* item;
					StaticEnumItems* items;

					items = memberInfo->GetValidationInfo()->GetStaticEnum()->GetItems();
					type = OleTypeOf(member->GetDataType());
					implCode_ += _T("STDMETHODIMP ") + GetClassName() + _T("::get_") + member->GetName() + _T("_Value(") + type + _T("* value)") + xCrLf;
					implCode_ += _T("{") + xCrLf;
					implCode_ += xTab + _T("USES_CONVERSION;") + xCrLf;
					implCode_ += xCrLf;
					implCode_ += xTab + _T("switch (") + GetCamelCase(member->GetName()) + _T("_) {") + xCrLf;
					
					type = _T("en") + memberInfo->GetName();

					for (int i = 0; i < items->size(); i++) {

						item = (*items)[i];

						implCode_ += xTab + xTab + _T("case ") + type + _T("_") + item->GetItemName() + _T(":") + xCrLf;
						implCode_ += xTab + xTab + xTab + _T("*value = ::SysAllocString(T2W(_T(\"") + item->GetItemValue() + _T("\")));") + xCrLf;
						implCode_ += xTab + xTab + xTab + _T("break;") + xCrLf;
					}
					implCode_ += xTab + _T("}") + xCrLf;
					
					implCode_ += xCrLf;
					implCode_ += xTab + _T("return S_OK;") + xCrLf;
					implCode_ += _T("}") + xCrLf;
					implCode_ += xCrLf;	
					
				} else {
					type = OleTypeOf(member->GetDataType());
				}

				implCode_ += _T("STDMETHODIMP ") + GetClassName() + _T("::get_") + member->GetName() + _T("(") + type + _T("* value)") + xCrLf;
				implCode_ += _T("{") + xCrLf;
				implCode_ += xTab + _T("USES_CONVERSION;") + xCrLf;
				implCode_ += xCrLf;
				if (memberInfo->GetValidationInfo()->GetValidationMode() == enValidationMode_StaticEnum) {
					implCode_ += xTab + _T("*value = ") + GetCamelCase(member->GetName()) + _T("_;") + xCrLf;
				} else {
					implCode_ += xTab + _T("*value = ") + GetCamelCase(member->GetName()) + _T("_.AllocSysString();") + xCrLf;
				}
				implCode_ += xCrLf;
				implCode_ += xTab + _T("return S_OK;") + xCrLf;
				implCode_ += _T("}") + xCrLf;
				implCode_ += xCrLf;

				implCode_ += _T("STDMETHODIMP ")+ GetClassName() + _T("::put_") + member->GetName() + _T("(") + type + _T(" value)") + xCrLf;
				implCode_ += _T("{") + xCrLf;
				//implCode_ += xTab + _T("USES_CONVERSION;") + xCrLf;
				//implCode_ += xCrLf;
				implCode_ += xTab + GetCamelCase(member->GetName()) + _T("_ = value;") + xCrLf;
				implCode_ += xCrLf;
				implCode_ += xTab + _T("return S_OK;") + xCrLf;
				implCode_ += _T("}") + xCrLf;
				implCode_ += xCrLf;
				break;
			
			default:
		
				memberInfo = dynamic_cast<CXmlMemberInfo*>(member);
				if (memberInfo->GetValidationInfo()->GetValidationMode() == enValidationMode_StaticEnum) {
					CXmlMemberValidation_StaticEnumItem* item;
					StaticEnumItems* items;

					items = memberInfo->GetValidationInfo()->GetStaticEnum()->GetItems();
					type = OleTypeOf(member->GetDataType());
					implCode_ += _T("STDMETHODIMP ") + GetClassName() + _T("::get_") + member->GetName() + _T("_Value(") + type + _T("* value)") + xCrLf;
					implCode_ += _T("{") + xCrLf;
					implCode_ += xTab + _T("USES_CONVERSION;") + xCrLf;
					implCode_ += xCrLf;
					implCode_ += xTab + _T("switch (") + GetCamelCase(member->GetName()) + _T("_) {") + xCrLf;
					
					type = _T("en") + memberInfo->GetName();

					for (int i = 0; i < items->size(); i++) {

						item = (*items)[i];

						implCode_ += xTab + xTab + _T("case ") + type + _T("_") + item->GetItemName() + _T(":") + xCrLf;
						implCode_ += xTab + xTab + xTab + _T("*value = ") + item->GetItemValue() + _T(";") + xCrLf;
						implCode_ += xTab + xTab + xTab + _T("break;") + xCrLf;
					}
					implCode_ += xTab + _T("}") + xCrLf;
					
					implCode_ += xCrLf;
					implCode_ += xTab + _T("return S_OK;") + xCrLf;
					implCode_ += _T("}") + xCrLf;
					implCode_ += xCrLf;	
				} else
					type = OleTypeOf(member->GetDataType());

				implCode_ += _T("STDMETHODIMP ") + GetClassName() + _T("::get_") + member->GetName() + _T("(") + type + _T("* value)") + xCrLf;
				implCode_ += _T("{") + xCrLf;
				implCode_ += xTab + _T("*value = ") + GetCamelCase(member->GetName()) + _T("_;") + xCrLf;
				implCode_ += xCrLf;
				implCode_ += xTab + _T("return S_OK;") + GetCamelCase(member->GetName()) + _T("_;") + xCrLf;
				implCode_ += _T("}") + xCrLf;
				implCode_ += xCrLf;

				implCode_ += _T("STDMETHODIMP ")+ GetClassName() + _T("::put_") + member->GetName() + _T("(") + type + _T(" value)") + xCrLf;
				implCode_ += _T("{") + xCrLf;
				implCode_ += xTab + GetCamelCase(member->GetName()) + _T("_ = value;") + xCrLf;
				implCode_ += xCrLf;
				implCode_ += xTab + _T("return S_OK;") + xCrLf;
				implCode_ += _T("}") + xCrLf;
				implCode_ += xCrLf;
				
		}

	}
}

void CAtlClassGenerator::Impl_generateSerialization()
{
	ClassMemberMap::iterator it;
	ClassMemberMap* members;
	CXmlBaseElement* element;
	CXmlMemberInfo* member;
	CXmlClassInfo* classInfo;
	//bool firstDone;
	cmString buf;
	cmString p;
	cmString name;
	//bool firstDone;

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

	implCode_ += xTab + _T("IXMLDOMNode* childNode = NULL;") + xCrLf;
	implCode_ += xTab + _T("cmString nodeValue;") + xCrLf;
	implCode_ += xCrLf;

	implCode_ += xTab + _T("SetDefaults();") + xCrLf;
	implCode_ += xTab + xCrLf;

	members = classInfo_->GetMembers();

	for(it = members->begin(); it != members->end(); it++) {
		element = it->second;
	
		if (element->GetDataType() == enDataType_Class) {
			enCardinality c;

			classInfo = dynamic_cast<CXmlClassInfo*>(element);	
			if (classInfo->GetDefinitionInheritance())
				classInfo = dynamic_cast<CXmlClassInfo*>(project_->GetRootElement()->GetMemberById(classInfo->GetInherithClassId()));
			
			p = GetCardinalityPostfix(classInfo);
			c = classInfo->GetCardinalityInfo()->GetCardinality();

			if ((c == enCardinality_Map || c == enCardinality_Array) && !classInfo->GetCardinalityInfo()->GetUseContainerNode()) {
				implCode_ += xTab + xTab + GetCamelCase(classInfo->GetName()) + p + _T("_->BuildFromXml(node);") + xCrLf;
			} else {
				implCode_ += xTab + _T("childNode = GetChildNode(node, _T(\"") + classInfo->GetName() + p + _T("\"), nodeValue);") + xCrLf;
				implCode_ += xTab + _T("if (childNode){") + xCrLf;
				implCode_ += xTab + xTab + GetCamelCase(classInfo->GetName()) + p + _T("_->BuildFromXml(childNode);") + xCrLf;
				implCode_ += xTab + xTab + _T("childNode->Release();") + xCrLf;
				implCode_ += xTab + _T("}") + xCrLf;
			}
		} else {
			member = dynamic_cast<CXmlMemberInfo*>(element);
			
			switch (member->GetPersistenceMode()) {
				case enPersistenceMode_AsChildNode:
					implCode_ += xTab + _T("ExtractMemberNode(node, _T(\"") + element->GetName() + _T("\"), ");
					if (member && member->GetValidationInfo()->GetValidationMode() == enValidationMode_StaticEnum) {
						// enum values need cast to int
						//
						implCode_ += _T("(int&)");
					} 
					implCode_ += GetCamelCase(element->GetName()) + _T("_);") + xCrLf;
					break;

				case enPersistenceMode_AsAttribute:
					implCode_ += xTab + _T("ExtractAttributeNode(node, _T(\"") + element->GetName() + _T("\"), ");
					if (member && member->GetValidationInfo()->GetValidationMode() == enValidationMode_StaticEnum) {
						// enum values need cast to int
						//
						implCode_ += _T("(int&)");
					} 
					implCode_ += GetCamelCase(element->GetName()) + _T("_);") + xCrLf;
					break;

				case enPersistenceMode_AsTextNode:
					implCode_ += xTab + _T("ExtractTextNode(node, ");
					if (member && member->GetValidationInfo()->GetValidationMode() == enValidationMode_StaticEnum) {
						// enum values need cast to int
						//
						implCode_ += _T("(int&)");
					} 
					implCode_ += GetCamelCase(element->GetName()) + _T("_);") + xCrLf;
					break;

				case enPersistenceMode_AsCDATA:
					implCode_ += xTab + _T("ExtractCDATAMemberNode(node, ") + GetCamelCase(element->GetName()) + _T("_);") + xCrLf;
					break;
			} // close switch
		}
	}

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

	//////////////////////////////////////////////////////////////////////
	// AppendToDOMDocument
	//
	implCode_ += _T("bool ") + GetClassName() + _T("::AppendToDOMDocument(IXMLDOMDocument2* xmlDoc, IXMLDOMElement* parentElement)") + xCrLf;
	implCode_ += _T("{") + xCrLf;
		
	implCode_ += xTab + _T("USES_CONVERSION;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("IXMLDOMElement* newElement;") + xCrLf;
	implCode_ += xTab + _T("HRESULT hr;") + xCrLf;
    //implCode_ += xTab + _T("CXMLDOMElement rectElement;") + xCrLf;
	//implCode_ += xTab + _T("CXMLDOMElement member;") + xCrLf + xCrLf;
   
    implCode_ += xTab + _T("hr = xmlDoc->createElement(CComBSTR((const TCHAR*)GetXmlNodeName()), &newElement);") + xCrLf;
	implCode_ += xCrLf;		
	members = classInfo_->GetMembers();
	for(it = members->begin(); it != members->end(); it++) {
		element = it->second;
	
		member = dynamic_cast<CXmlMemberInfo*>(element);
		switch (element->GetDataType()) {
			case enDataType_Class:
				classInfo = dynamic_cast<CXmlClassInfo*>(element);
				if (classInfo->GetDefinitionInheritance())
					classInfo = dynamic_cast<CXmlClassInfo*>(rootClassInfo_->GetMemberById(classInfo->GetInherithClassId()));
				
				p = GetCardinalityPostfix(classInfo);
				name = classInfo->GetName();
				implCode_ += xTab + GetCamelCase(name) + p + _T("_->AppendToDOMDocument(xmlDoc, newElement);") + xCrLf;
				break;

			case enDataType_Double:
				switch (member->GetPersistenceMode()) {
					case enPersistenceMode_AsChildNode:
						buf.Format(_T("%d"), (dynamic_cast<CXmlMemberInfo*>(element))->GetDecimalPlaces());
						implCode_ += xTab + _T("AppendMemberNode(_T(\"") + element->GetName() + _T("\"), ") + GetCamelCase(element->GetName()) + _T("_, ") + buf + _T(", newElement, xmlDoc);") + xCrLf;	
						break;

					case enPersistenceMode_AsAttribute:
						buf.Format(_T("%d"), (dynamic_cast<CXmlMemberInfo*>(element))->GetDecimalPlaces());
						implCode_ += xTab + _T("AppendAttributeNode(_T(\"") + element->GetName() + _T("\"), ") + GetCamelCase(element->GetName()) + _T("_, ") + buf + _T(", newElement, xmlDoc);") + xCrLf;	
						break;

					case enPersistenceMode_AsTextNode:
						buf.Format(_T("%d"), (dynamic_cast<CXmlMemberInfo*>(element))->GetDecimalPlaces());
						implCode_ += xTab + _T("AppendTextNode(") + GetCamelCase(element->GetName()) + _T("_, ") + buf + _T(", newElement, xmlDoc);") + xCrLf;	
						break;
				}
				break;

			default:
				switch (member->GetPersistenceMode()) {
					case enPersistenceMode_AsChildNode:
						implCode_ += xTab + _T("AppendMemberNode(_T(\"") + element->GetName() + _T("\"), ") + GetCamelCase(element->GetName()) + _T("_, newElement, xmlDoc);") + xCrLf;	
						break;
					
					case enPersistenceMode_AsAttribute:
						implCode_ += xTab + _T("AppendAttributeNode(_T(\"") + element->GetName() + _T("\"), ") + GetCamelCase(element->GetName()) + _T("_, newElement, xmlDoc);") + xCrLf;	
						break;

					case enPersistenceMode_AsTextNode:
						implCode_ += xTab + _T("AppendTextNode(") + GetCamelCase(element->GetName()) + _T("_, newElement, xmlDoc);") + xCrLf;	
						break;

					case enPersistenceMode_AsCDATA:
						implCode_ += xTab + _T("AppendCDATAMemberNode(") + GetCamelCase(element->GetName()) + _T("_, newElement, xmlDoc);") + xCrLf;	
						break;
				}
		}	
	}

	implCode_ += xCrLf;
	//implCode_ += xTab + _T("IXMLDOMNode* newOutNode;") + 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;
	//implCode_ += xTab + _T("newOutNode->Release();") + xCrLf;
	//implCode_ += xCrLf;
	implCode_ += xTab + _T("return true;") + xCrLf;

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

	/***
	implCode_ += _T("bool ") + GetClassName() + _T("::AppendToDOMDocument(CXMLDOMDocument2& xmlDoc, CXMLDOMElement& parentElement, bool parentIsValid)") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("USES_CONVERSION;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("CXMLDOMElement newElement;") + xCrLf;
    implCode_ += xTab + _T("CXMLDOMElement rectElement;") + xCrLf;
	implCode_ += xTab + _T("CXMLDOMElement member;") + xCrLf + xCrLf;
   
    implCode_ += xTab + _T("newElement = xmlDoc.CreateElement(GetXmlNodeName().c_str());") + xCrLf;
		
	members = classInfo_->GetMembers();
	for(it = members->begin(); it != members->end(); it++) {
		member = it->second;
	
		switch (member->GetDataType()) {
			case enDataType_Class:
				classInfo = dynamic_cast<CXmlClassInfo*>(member);
				if (classInfo->GetDefinitionInheritance())
					classInfo = dynamic_cast<CXmlClassInfo*>(rootClassInfo_->GetMemberById(classInfo->GetInherithClassId()));
				
				p = GetCardinalityPostfix(classInfo);
				name = classInfo->GetName();
				implCode_ += xTab + GetCamelCase(name) + p + _T("_->AppendToDOMDocument(xmlDoc, newElement);") + xCrLf;
				break;

			case enDataType_Double:
				wsprintf(buf, _T("%d"), (dynamic_cast<CXmlMemberInfo*>(member))->GetDecimalPlaces());
				implCode_ += xTab + _T("AppendMemberNode(\"") + GetCamelCase(member->GetName()) + _T("\", ") + GetCamelCase(member->GetName()) + _T("_, ") + cmString(buf) + _T(", newElement, xmlDoc);") + xCrLf;	
				break;

			case enDataType_String:
				implCode_ += xTab + _T("if(") + GetCamelCase(member->GetName()) + _T("_.length())") + xCrLf;
				implCode_ += xTab + xTab + _T("AppendMemberNode(\"") + GetCamelCase(member->GetName()) + _T("\", ") + GetCamelCase(member->GetName()) + _T("_, newElement, xmlDoc);") + xCrLf;	
				implCode_ += xTab + _T("else") + xCrLf;
				implCode_ += xTab + xTab + _T("AppendMemberNode(\"") + GetCamelCase(member->GetName()) + _T("\", \"\", newElement, xmlDoc);") + xCrLf;	
				break;

			case enDataType_Boolean:
				implCode_ += xTab + _T("AppendMemberNode(\"") + GetCamelCase(member->GetName()) + _T("\", ") + GetCamelCase(member->GetName()) + _T("_ == VARIANT_TRUE ? 1 : 0 , newElement, xmlDoc);") + xCrLf;	
				break;

			default:
				implCode_ += xTab + _T("AppendMemberNode(\"") + GetCamelCase(member->GetName()) + _T("\", ") + GetCamelCase(member->GetName()) + _T("_, newElement, xmlDoc);") + xCrLf;	
		}	
	}

	implCode_ += xCrLf;
	implCode_ += xTab + _T("if (!parentIsValid)") + xCrLf;
    implCode_ += xTab + xTab + _T("xmlDoc.AppendChild(newElement);") + xCrLf;
	implCode_ += xTab +_T("else") + xCrLf;
    implCode_ += xTab + xTab + _T("parentElement.AppendChild(newElement);") + xCrLf + xCrLf;
	implCode_ += xTab + _T("return true;") + xCrLf;
	implCode_ += _T("}") + xCrLf + xCrLf;
***/
	//////////////////////////////////////////////////////////////////////
	// loadFromFile
	//
	implCode_ += _T("STDMETHODIMP ") + GetClassName() + _T("::Load(BSTR fileName, VARIANT_BOOL* retval)") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("USES_CONVERSION;") + xCrLf;
	implCode_ += xTab + _T("bool ret;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("ret = LoadFromXmlFile(W2T(fileName));") + xCrLf;
	implCode_ += xTab + _T("*retval = ret ? VARIANT_TRUE : VARIANT_FALSE;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("return S_OK;") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;

	//////////////////////////////////////////////////////////////////////
	// saveToFile
	//
	
	implCode_ += _T("STDMETHODIMP ") + GetClassName() + _T("::Save(BSTR fileName, VARIANT_BOOL* retval)") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("USES_CONVERSION;") + xCrLf;
	implCode_ += xTab + _T("bool ret;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("ret = SaveToXmlFile(W2T(fileName));") + xCrLf;
	implCode_ += xTab + _T("*retval = ret ? VARIANT_TRUE : VARIANT_FALSE;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("return S_OK;") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;


}