// WSDLElements.h
//
//////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000 - 2002 Robert Cunnings. All rights reserved.
//
// You may copy, modify, distribute or publish this code free of charge.
//
// NO WARRANTY: This software is provided AS IS, without warranty of any kind.
//
//////////////////////////////////////////////////////////////////////
//
// WSDLElements.h - a collection of event handlers used to process WSDL XML.
// These handlers are pushed onto the processing stack as required by the
// main parser event handler owned by the SOAP processor.
// They are derived from the abstract base class 'WMWSDLEventHandler'.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_WMWSDLELEMENTS_H__56FAC337_D136_4FA3_AC7B_F229F23D2566__INCLUDED_)
#define AFX_WMWSDLELEMENTS_H__56FAC337_D136_4FA3_AC7B_F229F23D2566__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "XMLParser.h"
#define IGNORE_ELEMENT_HANDLER NULL

// processing fault exception object
class WMWebServicesDescFault
{
public:
	WMWebServicesDescFault(const wchar_t *pwszFaultCode, const wchar_t *pwszFaultString)
	{
		m_wstrFaultCode = pwszFaultCode;
		m_wstrFaultString = pwszFaultString;
	}
	~WMWebServicesDescFault() {}

	const wchar_t *GetFaultCode() { return m_wstrFaultCode.c_str(); }
	const wchar_t *GetFaultString() { return m_wstrFaultString.c_str(); }

private:
	wstring m_wstrFaultCode;
	wstring m_wstrFaultString;
};

// abstract base class for parsing event handlers
class WMWSDLEventHandler  
{
public:
	WMWSDLEventHandler() {}
	virtual ~WMWSDLEventHandler() {}
    virtual WMWSDLEventHandler *StartElement(const wstring& wstrURI,
											const wstring& wstrLocalName,
											const wstring& wstrQualifiedName,
											WMXMLAttributeMap& mapAttributes,
											NSPrefixMap& mapNSPrefixes,
											WMXMLElement *pElement) = 0;
	virtual bool EndElement(const wstring& wstrURI,
					const wstring& wstrLocalName,
					const wstring& wstrQualifiedName,
					WMXMLElement *pElement) { return true; }

    virtual void Characters(const wstring& wstrChars) {}

    virtual void ReadAttributes(WMXMLAttributeMap& mapAttributes, NSPrefixMap& mapNSPrefixes) {}
	virtual void SetNamespace(const wstring& wstrNS) { m_wstrNS = wstrNS; }
	virtual const wstring& GetNamespace() { return m_wstrNS; }
	bool IsXSDType(const wstring& wstrTypeNS);
	bool IsSoapEncType(const wstring& wstrTypeNS);
	bool IsWSDLType(const wstring& wstrTypeNS);
	bool WMWSDLEventHandler::GetXSDAttribute(const wstring& wstrElemAttrNames,
											 WMXMLAttributeMap& mapAttributes,
											 WMXMLAttributeMap::iterator& iter);

protected:
	wstring		m_wstrNS;
};

// parsing event handlers

class WMSchemaHandler;
class WMSchemaSimpleTypeHandler;
class WMSchemaComplexTypeHandler;

class WMSchemaElemHandler : public WMWSDLEventHandler  
{
public:
	WMSchemaElemHandler()
	{
		m_bIsRef = false;
		m_bElemFormDefQualified = false;
		m_pComplexType = NULL;
		m_pSimpleType = NULL;
		m_pSchema = NULL;
        m_wstrMinOccurs = L"0";
        m_wstrMaxOccurs = L"1";
	}
	virtual ~WMSchemaElemHandler() {}
    WMWSDLEventHandler *StartElement(const wstring& wstrURI,
									const wstring& wstrLocalName,
									const wstring& wstrQualifiedName,
									WMXMLAttributeMap& mapAttributes,
									NSPrefixMap& mapNSPrefixes,
									WMXMLElement *pElement);
	bool EndElement(const wstring& wstrURI,
					const wstring& wstrLocalName,
					const wstring& wstrQualifiedName,
					WMXMLElement *pElement);
    void ReadAttributes(WMXMLAttributeMap& mapAttributes, NSPrefixMap& mapNSPrefixes);
	void GetType(wstring& wstrType, wstring& wstrTypeNS)
	{
		wstrType = m_wstrType;
		wstrTypeNS = m_wstrTypeNS;
	}
	void GetNames(wstring& wstrName, wstring& wstrNS)
	{
		wstrName = m_wstrName;
		wstrNS = m_wstrNS;
	}
	void SetTNS(const wstring& wstrTNS) { m_wstrTNS = wstrTNS; }
	const wstring& GetTNS() { return m_wstrTNS; }
	bool IsRef() { return m_bIsRef; }
	void SetElemFormDefault(bool bValue) { m_bElemFormDefQualified = bValue; }
    const wstring& GetElemForm() { return m_wstrElemForm; }
	bool IsAnonComplexType() { return m_pComplexType != NULL; }
	bool IsAnonSimpleType() { return m_pSimpleType != NULL; }
    const wstring& GetMinOccurs() { return m_wstrMinOccurs; }
    const wstring& GetMaxOccurs() { return m_wstrMaxOccurs; }
	WMSchemaComplexTypeHandler *DetachComplexType()
	{
		WMSchemaComplexTypeHandler *pType = m_pComplexType;
		m_pComplexType = NULL;
		return pType;
	}
	WMSchemaSimpleTypeHandler *DetachSimpleType()
	{
		WMSchemaSimpleTypeHandler *pType = m_pSimpleType;
		m_pSimpleType = NULL;
		return pType;
	}
	void SetSchema(WMSchemaHandler *pSchema) { m_pSchema = pSchema; }

protected:
	wstring						m_wstrTNS;
	wstring						m_wstrName;
	wstring						m_wstrType;
	wstring						m_wstrTypeNS;
    wstring                     m_wstrMinOccurs;
    wstring                     m_wstrMaxOccurs;
    wstring                     m_wstrElemForm;
	bool						m_bIsRef;
	bool						m_bElemFormDefQualified;
	WMSchemaSimpleTypeHandler	*m_pSimpleType;
	WMSchemaComplexTypeHandler	*m_pComplexType;
	WMSchemaHandler				*m_pSchema;
};

class WMSequenceHandler : public WMWSDLEventHandler  
{
public:
	WMSequenceHandler()
	{
		m_bElemFormDefQualified = false;
		m_pSchema = NULL;
	}
	virtual ~WMSequenceHandler()
	{
		list<WMSchemaElemHandler *>::iterator iL;
		for (iL = m_listSchemaElems.begin();
			iL != m_listSchemaElems.end(); iL++)
		{
			delete *iL;
		}
	}
    WMWSDLEventHandler *StartElement(const wstring& wstrURI,
									const wstring& wstrLocalName,
									const wstring& wstrQualifiedName,
									WMXMLAttributeMap& mapAttributes,
									NSPrefixMap& mapNSPrefixes,
									WMXMLElement *pElement);
	void SetTNS(const wstring& wstrTNS) { m_wstrTNS = wstrTNS; }
	const wstring& GetTNS() { return m_wstrTNS; }
	list<WMSchemaElemHandler *>& GetSchemaElemList() { return m_listSchemaElems; }
	void SetElemFormDefault(bool bValue) { m_bElemFormDefQualified = bValue; }
	void SetSchema(WMSchemaHandler *pSchema) { m_pSchema = pSchema; }

protected:
	wstring							m_wstrTNS;
	list<WMSchemaElemHandler *>		m_listSchemaElems;
	bool							m_bElemFormDefQualified;
	WMSchemaHandler					*m_pSchema;
};

class WMAttributeHandler : public WMWSDLEventHandler  
{
public:
	WMAttributeHandler()
	{
		m_bIsRef = false;
		m_pSchema = NULL;
	}
	virtual ~WMAttributeHandler() {}
    WMWSDLEventHandler *StartElement(const wstring& wstrURI,
									const wstring& wstrLocalName,
									const wstring& wstrQualifiedName,
									WMXMLAttributeMap& mapAttributes,
									NSPrefixMap& mapNSPrefixes,
									WMXMLElement *pElement)
	{ return IGNORE_ELEMENT_HANDLER; }
    void ReadAttributes(WMXMLAttributeMap& mapAttributes, NSPrefixMap& mapNSPrefixes);
	const wstring& GetName() { return m_wstrName; }
	void GetTypeNames(wstring& wstrType, wstring& wstrTypeNS)
	{
		wstrType = m_wstrType;
		wstrTypeNS = m_wstrTypeNS;
	}
	void GetRefNames(wstring& wstrRef, wstring& wstrRefNS)
	{
		wstrRef = m_wstrRef;
		wstrRefNS = m_wstrRefNS;
	}
	bool IsRef() { return m_bIsRef; }
	void SetSchema(WMSchemaHandler *pSchema) { m_pSchema = pSchema; }

protected:
	wstring				m_wstrName;
	wstring				m_wstrType;
	wstring				m_wstrTypeNS;
	wstring				m_wstrRef;
	wstring				m_wstrRefNS;
	bool				m_bIsRef;
	WMSchemaHandler		*m_pSchema;
};

class WMArrayTypeAttrHandler : public WMAttributeHandler  
{
public:
	WMArrayTypeAttrHandler() { m_pSchema = NULL; }
	virtual ~WMArrayTypeAttrHandler() {}
    WMWSDLEventHandler *StartElement(const wstring& wstrURI,
									const wstring& wstrLocalName,
									const wstring& wstrQualifiedName,
									WMXMLAttributeMap& mapAttributes,
									NSPrefixMap& mapNSPrefixes,
									WMXMLElement *pElement)
	{ return IGNORE_ELEMENT_HANDLER; }
    void ReadAttributes(WMXMLAttributeMap& mapAttributes, NSPrefixMap& mapNSPrefixes);
	bool GetArrayType(wstring& wstrType, wstring& wstrTypeNS);
	unsigned int GetArrayDims();
	const wstring& GetArraySize() { return m_wstrArraySize; }
	void SetSchema(WMSchemaHandler *pSchema) { m_pSchema = pSchema; }

protected:
	wstring				m_wstrArrayType;
	wstring				m_wstrArrayTypeNS;
	wstring				m_wstrArraySize;
	WMSchemaHandler		*m_pSchema;
};

class WMExtensionHandler : public WMWSDLEventHandler  
{
public:
	WMExtensionHandler() { m_pSchema = NULL; }
	virtual ~WMExtensionHandler()
	{
		list<WMAttributeHandler *>::iterator iL;
		for (iL = m_listAttributes.begin();
			iL != m_listAttributes.end(); iL++)
		{
			delete *iL;
		}
	}
    WMWSDLEventHandler *StartElement(const wstring& wstrURI,
									const wstring& wstrLocalName,
									const wstring& wstrQualifiedName,
									WMXMLAttributeMap& mapAttributes,
									NSPrefixMap& mapNSPrefixes,
									WMXMLElement *pElement);
    void ReadAttributes(WMXMLAttributeMap& mapAttributes, NSPrefixMap& mapNSPrefixes);
	void GetBaseTypeNames(wstring& wstrType, wstring& wstrTypeNS)
	{
		wstrTypeNS = m_wstrBaseTypeNS;
		wstrType = m_wstrBaseType;
	}
	void SetTNS(const wstring& wstrTNS) { m_wstrTNS = wstrTNS; }
	const wstring& GetTNS() { return m_wstrTNS; }
	list<WMAttributeHandler *>& GetAttributeList() { return m_listAttributes; }
	void SetElemFormDefault(bool bValue) { m_bElemFormDefQualified = bValue; }
	void SetSchema(WMSchemaHandler *pSchema) { m_pSchema = pSchema; }
    WMSequenceHandler& GetSequence() { return m_Sequence; }

protected:
	wstring							m_wstrTNS;
	wstring							m_wstrBaseType;
	wstring							m_wstrBaseTypeNS;
	list<WMAttributeHandler *>		m_listAttributes;
	WMSequenceHandler				m_Sequence;
	bool							m_bElemFormDefQualified;
	WMSchemaHandler					*m_pSchema;
};

class WMRestrictionHandler : public WMWSDLEventHandler  
{
public:
	WMRestrictionHandler()
    {
        m_pSchema = NULL;
        m_bArrayTypeHandlerFound = false;
    }
	virtual ~WMRestrictionHandler()
	{
		list<WMAttributeHandler *>::iterator iL;
		for (iL = m_listAttributes.begin();
			iL != m_listAttributes.end(); iL++)
		{
			delete *iL;
		}
	}
    WMWSDLEventHandler *StartElement(const wstring& wstrURI,
									const wstring& wstrLocalName,
									const wstring& wstrQualifiedName,
									WMXMLAttributeMap& mapAttributes,
									NSPrefixMap& mapNSPrefixes,
									WMXMLElement *pElement);
    void ReadAttributes(WMXMLAttributeMap& mapAttributes, NSPrefixMap& mapNSPrefixes);
	void GetBaseTypeNames(wstring& wstrType, wstring& wstrTypeNS)
	{
		wstrTypeNS = m_wstrBaseTypeNS;
		wstrType = m_wstrBaseType;
	}
	bool GetArrayType(wstring& wstrType, wstring& wstrTypeNS, bool& bIsRef);
	bool GetArrayTypeLit(   wstring& wstrType,
                            wstring& wstrTypeNS,
                            wstring& wstrElemName,
                            wstring& wstrElemNS,
                            bool& bIsRef);
	unsigned int GetArrayDims();
	void SetTNS(const wstring& wstrTNS) { m_wstrTNS = wstrTNS; }
	const wstring& GetTNS() { return m_wstrTNS; }
	list<WMAttributeHandler *>& GetAttributeList() { return m_listAttributes; }
	void SetElemFormDefault(bool bValue) { m_bElemFormDefQualified = bValue; }
	void SetSchema(WMSchemaHandler *pSchema) { m_pSchema = pSchema; }
    WMSequenceHandler& GetSequence() { return m_Sequence; }

protected:
	wstring							m_wstrTNS;
	wstring							m_wstrBaseType;
	wstring							m_wstrBaseTypeNS;
	list<WMAttributeHandler *>		m_listAttributes;
	WMArrayTypeAttrHandler			m_ArrayTypeHandler;
	WMSequenceHandler				m_Sequence;
	bool							m_bElemFormDefQualified;
	WMSchemaHandler					*m_pSchema;
    bool                            m_bArrayTypeHandlerFound;
};

class WMSimpleContentHandler : public WMWSDLEventHandler  
{
public:
	WMSimpleContentHandler()
	{
		m_bIsRestriction = false;
		m_bIsExtension = false;
		m_pSchema = NULL;
	}
	virtual ~WMSimpleContentHandler() {}
    WMWSDLEventHandler *StartElement(const wstring& wstrURI,
									const wstring& wstrLocalName,
									const wstring& wstrQualifiedName,
									WMXMLAttributeMap& mapAttributes,
									NSPrefixMap& mapNSPrefixes,
									WMXMLElement *pElement);
	void SetTNS(const wstring& wstrTNS) { m_wstrTNS = wstrTNS; }
	const wstring& GetTNS() { return m_wstrTNS; }
	WMRestrictionHandler& GetRestriction() { return m_Restriction; }
	WMExtensionHandler& GetExtension() { return m_Extension; }
	bool IsRestriction() { return (m_bIsRestriction == true); }
	bool IsExtension() { return (m_bIsExtension == true); }
	void GetBaseTypeNames(wstring& wstrType, wstring& wstrTypeNS);
	void SetElemFormDefault(bool bValue) { m_bElemFormDefQualified = bValue; }
	void SetSchema(WMSchemaHandler *pSchema) { m_pSchema = pSchema; }

protected:
	wstring							m_wstrTNS;
	WMRestrictionHandler			m_Restriction;
	WMExtensionHandler				m_Extension;
	bool							m_bIsRestriction;
	bool							m_bIsExtension;
	bool							m_bElemFormDefQualified;
	WMSchemaHandler					*m_pSchema;
};

class WMComplexContentHandler : public WMWSDLEventHandler  
{
public:
	WMComplexContentHandler()
	{
		m_bIsRestriction = false;
		m_bIsExtension = false;
		m_pSchema = NULL;
	}
	virtual ~WMComplexContentHandler() {}
    WMWSDLEventHandler *StartElement(const wstring& wstrURI,
									const wstring& wstrLocalName,
									const wstring& wstrQualifiedName,
									WMXMLAttributeMap& mapAttributes,
									NSPrefixMap& mapNSPrefixes,
									WMXMLElement *pElement);
	void SetTNS(const wstring& wstrTNS) { m_wstrTNS = wstrTNS; }
	const wstring& GetTNS() { return m_wstrTNS; }
	WMRestrictionHandler& GetRestriction() { return m_Restriction; }
	WMExtensionHandler& GetExtension() { return m_Extension; }
	bool IsRestriction() { return (m_bIsRestriction == true); }
	bool IsExtension() { return (m_bIsExtension == true); }
	void GetBaseTypeNames(wstring& wstrType, wstring& wstrTypeNS);
	void SetElemFormDefault(bool bValue) { m_bElemFormDefQualified = bValue; }
	void SetSchema(WMSchemaHandler *pSchema) { m_pSchema = pSchema; }

protected:
	wstring							m_wstrTNS;
	WMRestrictionHandler			m_Restriction;
	WMExtensionHandler				m_Extension;
	bool							m_bIsRestriction;
	bool							m_bIsExtension;
	bool							m_bElemFormDefQualified;
	WMSchemaHandler					*m_pSchema;
};

class WMSchemaSimpleTypeHandler : public WMWSDLEventHandler  
{
public:
	WMSchemaSimpleTypeHandler()
	{
		m_bIsDerivation = false;
		m_pSchema = NULL;
	}
	virtual ~WMSchemaSimpleTypeHandler() {}
    WMWSDLEventHandler *StartElement(const wstring& wstrURI,
									const wstring& wstrLocalName,
									const wstring& wstrQualifiedName,
									WMXMLAttributeMap& mapAttributes,
									NSPrefixMap& mapNSPrefixes,
									WMXMLElement *pElement);
	void ReadAttributes(WMXMLAttributeMap& mapAttributes, NSPrefixMap& mapNSPrefixes) {}
	void GetBaseTypeNames(wstring& wstrType, wstring& wstrTypeNS)
	{
		m_Restriction.GetBaseTypeNames(wstrType, wstrTypeNS);
	}
	void SetTNS(const wstring& wstrTNS) { m_wstrTNS = wstrTNS; }
	const wstring& GetTNS() { return m_wstrTNS; }
	WMRestrictionHandler& GetRestriction() { return m_Restriction; }
	bool IsRestriction() { return (m_bIsRestriction == true); }
	void SetElemFormDefault(bool bValue) { m_bElemFormDefQualified = bValue; }
	void SetSchema(WMSchemaHandler *pSchema) { m_pSchema = pSchema; }

protected:
	bool						m_bIsDerivation;
	wstring						m_wstrTNS;
	wstring						m_wstrBaseType;
	wstring						m_wstrBaseTypeNS;
	WMRestrictionHandler		m_Restriction;
	bool						m_bIsRestriction;
	bool						m_bElemFormDefQualified;
	WMSchemaHandler				*m_pSchema;
};

class WMSchemaComplexTypeHandler : public WMWSDLEventHandler  
{
public:
	WMSchemaComplexTypeHandler()
	{
		m_bIsDerivation = false;
		m_bElemFormDefQualified = false;
		m_bIsSimpleContent = false;
		m_bIsComplexContent = false;
		m_pSchema = NULL;
	}
	virtual ~WMSchemaComplexTypeHandler()
	{
		list<WMAttributeHandler *>::iterator iL;
		for (iL = m_listAttributes.begin();
			iL != m_listAttributes.end(); iL++)
		{
			delete *iL;
		}
	}
    WMWSDLEventHandler *StartElement(const wstring& wstrURI,
									const wstring& wstrLocalName,
									const wstring& wstrQualifiedName,
									WMXMLAttributeMap& mapAttributes,
									NSPrefixMap& mapNSPrefixes,
									WMXMLElement *pElement);
	void ReadAttributes(WMXMLAttributeMap& mapAttributes, NSPrefixMap& mapNSPrefixes) {}
	void GetBaseTypeNames(wstring& wstrType, wstring& wstrTypeNS);
	bool GetElementType(const wstring& wstrName, const wstring& wstrNS, wstring& wstrType, wstring& wstrTypeNS, bool& bIsRef);
	bool GetArrayType(wstring& wstrType, wstring& wstrTypeNS, bool& bIsRef);
	bool GetArrayTypeLit(   wstring& wstrType,
                            wstring& wstrTypeNS,
                            wstring& wstrElemName,
                            wstring& wstrElemNS,
                            bool& bIsRef);
	unsigned int GetArrayDims();
	void SetTNS(const wstring& wstrTNS) { m_wstrTNS = wstrTNS; }
	const wstring& GetTNS() { return m_wstrTNS; }
	WMSequenceHandler& GetSchemaSequence() { return m_Sequence; }
	WMSimpleContentHandler& GetSimpleContent() { return m_SimpleContent; }
	WMComplexContentHandler& GetComplexContent() { return m_ComplexContent; }
	bool IsSimpleContent() { return (m_bIsSimpleContent == true); }
	bool IsComplexContent() { return (m_bIsComplexContent == true); }
	void SetElemFormDefault(bool bValue) { m_bElemFormDefQualified = bValue; }
	list<WMAttributeHandler *>& GetAttributeList();
	void SetSchema(WMSchemaHandler *pSchema) { m_pSchema = pSchema; }
    bool IsExtension()
    {
        if (m_bIsComplexContent == true)
        {
            return m_ComplexContent.IsExtension();
        }
        else if (m_bIsSimpleContent == true)
        {
            return m_SimpleContent.IsExtension();
        }
        return false;
    }

protected:
	bool						m_bIsDerivation;
	wstring						m_wstrTNS;
	WMSequenceHandler			m_Sequence;
	WMSimpleContentHandler		m_SimpleContent;
	WMComplexContentHandler		m_ComplexContent;
	bool						m_bIsSimpleContent;
	bool						m_bIsComplexContent;
	bool						m_bElemFormDefQualified;
	list<WMAttributeHandler *>	m_listAttributes;
	WMSchemaHandler				*m_pSchema;
};

class WMSchemaHandler : public WMWSDLEventHandler  
{
public:
	WMSchemaHandler() { m_bElemFormDefQualified = false; }
	virtual ~WMSchemaHandler()
	{
		map<wstring, WMSchemaElemHandler *>::iterator iM1;
		for (iM1 = m_mapSchemaElems.begin();
			iM1 != m_mapSchemaElems.end(); iM1++)
		{
			delete (*iM1).second;
		}
		map<wstring, WMSchemaComplexTypeHandler *>::iterator iM2;
		for (iM2 = m_mapSchemaComplexTypes.begin();
			iM2 != m_mapSchemaComplexTypes.end(); iM2++)
		{
			delete (*iM2).second;
		}
		map<wstring, WMSchemaSimpleTypeHandler *>::iterator iM3;
		for (iM3 = m_mapSchemaSimpleTypes.begin();
			iM3 != m_mapSchemaSimpleTypes.end(); iM3++)
		{
			delete (*iM3).second;
		}
	}
    WMWSDLEventHandler *StartElement(const wstring& wstrURI,
									const wstring& wstrLocalName,
									const wstring& wstrQualifiedName,
									WMXMLAttributeMap& mapAttributes,
									NSPrefixMap& mapNSPrefixes,
									WMXMLElement *pElement);
    void ReadAttributes(WMXMLAttributeMap& mapAttributes, NSPrefixMap& mapNSPrefixes);
	const wstring& GetTNS() { return m_wstrTNS; }
	WMSchemaElemHandler *GetSchemaElem(const wstring& wstrSchemaElemName,
										const wstring& wstrNamespace);
	WMSchemaSimpleTypeHandler *GetSimpleType(const wstring& wstrTypeName,
												const wstring& wstrTypeNS);
	WMSchemaComplexTypeHandler *GetComplexType(const wstring& wstrTypeName,
												const wstring& wstrTypeNS);
	void Merge(WMSchemaHandler *pSchema);
	map<wstring, WMSchemaElemHandler *>& GetSchemaElemMap() { return m_mapSchemaElems; }
	map<wstring, WMSchemaSimpleTypeHandler *>& GetSimpleTypeMap() { return m_mapSchemaSimpleTypes; }
	map<wstring, WMSchemaComplexTypeHandler *>& GetComplexTypeMap() { return m_mapSchemaComplexTypes; }

protected:
	wstring										m_wstrTNS;
	map<wstring, WMSchemaElemHandler *>			m_mapSchemaElems;
	map<wstring, WMSchemaSimpleTypeHandler *>	m_mapSchemaSimpleTypes;
	map<wstring, WMSchemaComplexTypeHandler *>	m_mapSchemaComplexTypes;
	bool										m_bElemFormDefQualified;
};

class WMTypesHandler : public WMWSDLEventHandler  
{
public:
	WMTypesHandler() {}
	virtual ~WMTypesHandler()
	{
		map<wstring, WMSchemaHandler *>::iterator iM;
		for (iM = m_mapSchemas.begin();
			iM != m_mapSchemas.end(); iM++)
		{
			delete (*iM).second;
		}
	}
    WMWSDLEventHandler *StartElement(const wstring& wstrURI,
									const wstring& wstrLocalName,
									const wstring& wstrQualifiedName,
									WMXMLAttributeMap& mapAttributes,
									NSPrefixMap& mapNSPrefixes,
									WMXMLElement *pElement);
	void MergeSchemas(const wstring& wstrTargetNS, WMTypesHandler& Types)
	{
		// steal the schema element pointers in map
		map<wstring, WMSchemaHandler *>::iterator iM1;
		for (iM1 = Types.m_mapSchemas.begin(); iM1 != Types.m_mapSchemas.end();)
		{
			// is schema with this namespace already present?
			map<wstring, WMSchemaHandler *>::iterator iM2;
			if ((iM2 = m_mapSchemas.find((*iM1).first)) != m_mapSchemas.end())
			{
				// yes, so merge
				(*iM2).second->Merge((*iM1).second);
				iM1++;
				continue;
			}
			else
			{
				// no, so add entire schema to destination map, erase from source map
				m_mapSchemas.insert(map<wstring,
				WMSchemaHandler *>::value_type((*iM1).first, (*iM1).second));
				iM1 = Types.m_mapSchemas.erase(iM1);
			}
		}
	}
	WMSchemaHandler *GetSchema(const wstring& wstrSchemaTNS);
	map<wstring, WMSchemaHandler *>& GetSchemaMap() { return m_mapSchemas; }

protected:
	map<wstring, WMSchemaHandler *>	m_mapSchemas;
};

class WMWSDLNullHandler : public WMWSDLEventHandler
{
public:
    WMWSDLEventHandler *StartElement(const wstring& wstrURI,
									const wstring& wstrLocalName,
									const wstring& wstrQualifiedName,
									WMXMLAttributeMap& mapAttributes,
									NSPrefixMap& mapNSPrefixes,
									WMXMLElement *pElement)
	{ return IGNORE_ELEMENT_HANDLER; }

	bool EndElement(const wstring& wstrURI,
					const wstring& wstrLocalName,
					const wstring& wstrQualifiedName)
	{ delete this; return true; }
};

class WMFaultHandler : public WMWSDLEventHandler  
{
public:
	WMFaultHandler() {}
	virtual ~WMFaultHandler() {}
    WMWSDLEventHandler *StartElement(const wstring& wstrURI,
									const wstring& wstrLocalName,
									const wstring& wstrQualifiedName,
									WMXMLAttributeMap& mapAttributes,
									NSPrefixMap& mapNSPrefixes,
									WMXMLElement *pElement)
	{ return IGNORE_ELEMENT_HANDLER; }
    void ReadAttributes(WMXMLAttributeMap& mapAttributes, NSPrefixMap& mapNSPrefixes);
	const wstring& GetName() { return m_wstrName; }
	void GetMessage(wstring& wstrMessage, wstring& wstrMessageNS)
	{
		wstrMessage = m_wstrMessage;
		wstrMessageNS = m_wstrMessageNS;
	}

protected:
	wstring		m_wstrName;
	wstring		m_wstrMessage;
	wstring		m_wstrMessageNS;
};

class WMInputHandler : public WMWSDLEventHandler  
{
public:
	WMInputHandler() {}
	virtual ~WMInputHandler() {}
    WMWSDLEventHandler *StartElement(const wstring& wstrURI,
									const wstring& wstrLocalName,
									const wstring& wstrQualifiedName,
									WMXMLAttributeMap& mapAttributes,
									NSPrefixMap& mapNSPrefixes,
									WMXMLElement *pElement)
	{ return IGNORE_ELEMENT_HANDLER; }
    void ReadAttributes(WMXMLAttributeMap& mapAttributes, NSPrefixMap& mapNSPrefixes);

	void GetMessageName(wstring& wstrMsgName, wstring& wstrMsgNamespace)
	{
		wstrMsgName = m_wstrMessage;
		wstrMsgNamespace = m_wstrMessageNS;
	}

protected:
	wstring		m_wstrName;
	wstring		m_wstrMessage;
	wstring		m_wstrMessageNS;
};

class WMOutputHandler : public WMWSDLEventHandler  
{
public:
	WMOutputHandler() {}
	virtual ~WMOutputHandler() {}
    WMWSDLEventHandler *StartElement(const wstring& wstrURI,
									const wstring& wstrLocalName,
									const wstring& wstrQualifiedName,
									WMXMLAttributeMap& mapAttributes,
									NSPrefixMap& mapNSPrefixes,
									WMXMLElement *pElement)
	{ return IGNORE_ELEMENT_HANDLER; }
    void ReadAttributes(WMXMLAttributeMap& mapAttributes, NSPrefixMap& mapNSPrefixes);

	void GetMessageName(wstring& wstrMsgName, wstring& wstrMsgNamespace)
	{
		wstrMsgName = m_wstrMessage;
		wstrMsgNamespace = m_wstrMessageNS;
	}

protected:
	wstring		m_wstrName;
	wstring		m_wstrMessage;
	wstring		m_wstrMessageNS;
};

class WMMessagePartHandler : public WMWSDLEventHandler  
{
public:
	WMMessagePartHandler() {}
	WMMessagePartHandler(WMMessagePartHandler& MsgPart)
	{
		m_wstrElement = MsgPart.m_wstrElement;
		m_wstrElementNS = MsgPart.m_wstrElementNS;
		m_wstrType = MsgPart.m_wstrType;
		m_wstrTypeNS = MsgPart.m_wstrTypeNS;
	}
	virtual ~WMMessagePartHandler() {}
    void ReadAttributes(WMXMLAttributeMap& mapAttributes, NSPrefixMap& mapNSPrefixes);
    WMWSDLEventHandler *StartElement(const wstring& wstrURI,
									const wstring& wstrLocalName,
									const wstring& wstrQualifiedName,
									WMXMLAttributeMap& mapAttributes,
									NSPrefixMap& mapNSPrefixes,
									WMXMLElement *pElement)
	{ return IGNORE_ELEMENT_HANDLER; }

	void GetType(wstring& wstrType, wstring& wstrTypeNS)
	{
		wstrType = m_wstrType;
		wstrTypeNS = m_wstrTypeNS;
	}
	void GetElement(wstring& wstrElement, wstring& wstrElementNS)
	{
		wstrElement = m_wstrElement;
		wstrElementNS = m_wstrElementNS;
	}

protected:
	wstring		m_wstrElement;
	wstring		m_wstrElementNS;
	wstring		m_wstrType;
	wstring		m_wstrTypeNS;
};

class WMMessageHandler : public WMWSDLEventHandler  
{
public:
	WMMessageHandler(WMTypesHandler& Types) : m_Types(Types) { 
		m_pDefaultPart = NULL;
	}
	WMMessageHandler(WMTypesHandler& Types, WMMessageHandler& MsgHandler) : m_Types(Types)
	{
		m_pDefaultPart = NULL;
		// copy parts map
		map<wstring, WMMessagePartHandler *>::iterator iM;
		for (iM = MsgHandler.m_mapParts.begin();
			iM != MsgHandler.m_mapParts.end(); iM++)
		{
			WMMessagePartHandler *pTemp = new WMMessagePartHandler(*((*iM).second));
			pTemp->SetNamespace((*iM).second->GetNamespace());
			// insert into map
			m_mapParts.insert(map<wstring,
				WMMessagePartHandler *>::value_type((*iM).first, pTemp));
			// copy default part
			if ((*iM).second == MsgHandler.m_pDefaultPart)
			{
				m_pDefaultPart = pTemp;
			}
		}
	}
	virtual ~WMMessageHandler()
	{
		map<wstring, WMMessagePartHandler *>::iterator iM;
		for (iM = m_mapParts.begin();
			iM != m_mapParts.end(); iM++)
		{
			delete (*iM).second;
		}
	}

    WMWSDLEventHandler *StartElement(const wstring& wstrURI,
									const wstring& wstrLocalName,
									const wstring& wstrQualifiedName,
									WMXMLAttributeMap& mapAttributes,
									NSPrefixMap& mapNSPrefixes,
									WMXMLElement *pElement);

	WMMessagePartHandler *GetMessagePart(   const wstring& wstrPartName);
	WMMessagePartHandler *GetDefaultPart() { return m_pDefaultPart; }
	bool GetMessagePartType(const wstring& wstrPartName,
							wstring& wstrType,
							wstring& wstrTypeNS);
	bool GetDefaultPartType(wstring& wstrType,
							wstring& wstrTypeNS);

	map<wstring, WMMessagePartHandler *>& GetPartsMap() { return m_mapParts; }

protected:
	map<wstring, WMMessagePartHandler *>	m_mapParts;
	WMMessagePartHandler *					m_pDefaultPart;
	WMTypesHandler&							m_Types;	
};

class WMOperationHandler : public WMWSDLEventHandler  
{
public:
	WMOperationHandler() {}
	virtual ~WMOperationHandler()
	{
		map<wstring, WMFaultHandler *>::iterator iM;
		for (iM = m_mapFaults.begin();
			iM != m_mapFaults.end(); iM++)
		{
			delete (*iM).second;
		}
	}
    WMWSDLEventHandler *StartElement(const wstring& wstrURI,
									const wstring& wstrLocalName,
									const wstring& wstrQualifiedName,
									WMXMLAttributeMap& mapAttributes,
									NSPrefixMap& mapNSPrefixes,
									WMXMLElement *pElement);
    void ReadAttributes(WMXMLAttributeMap& mapAttributes, NSPrefixMap& mapNSPrefixes);

	const wstring& GetParameterOrder() { return m_wstrParameterOrder; }
	bool GetParamOrderIndex(const wstring& wstrParam, int& nIndex);

	WMFaultHandler *GetFault(const wstring& wstrName);

	void GetInputMessageNames(wstring& wstrMsgName,	wstring& wstrMsgNamespace)
	{ m_Input.GetMessageName(wstrMsgName, wstrMsgNamespace); }

	void GetOutputMessageNames(wstring& wstrMsgName, wstring& wstrMsgNamespace)
	{ m_Output.GetMessageName(wstrMsgName, wstrMsgNamespace); }

	map<wstring, WMFaultHandler	*>& GetFaultMap() { return m_mapFaults; }

protected:
	WMInputHandler		m_Input;
	WMOutputHandler		m_Output;
	map<wstring, WMFaultHandler	*>	m_mapFaults;
	map<wstring, int>				m_mapParamOrder;
	wstring							m_wstrParameterOrder;
};

class WMPortTypeHandler : public WMWSDLEventHandler  
{
public:
	WMPortTypeHandler() {}
	virtual ~WMPortTypeHandler()
	{
		map<wstring, WMOperationHandler *>::iterator iM;
		for (iM = m_mapOperations.begin();
			iM != m_mapOperations.end(); iM++)
		{
			delete (*iM).second;
		}
	}
    WMWSDLEventHandler *StartElement(const wstring& wstrURI,
									const wstring& wstrLocalName,
									const wstring& wstrQualifiedName,
									WMXMLAttributeMap& mapAttributes,
									NSPrefixMap& mapNSPrefixes,
									WMXMLElement *pElement);

	map <wstring, WMOperationHandler *>& GetOperationMap() { return m_mapOperations; }
	WMOperationHandler *GetOperation(const wstring& wstrOpName);

protected:
	map<wstring, WMOperationHandler *>	m_mapOperations;
};

class WMBindingHandler : public WMWSDLEventHandler  
{
public:
	WMBindingHandler() {}
	virtual ~WMBindingHandler()
	{
		map<wstring, WMOperationHandler *>::iterator iM;
		for (iM = m_mapOperations.begin();
			iM != m_mapOperations.end(); iM++)
		{
			delete (*iM).second;
		}
	}
    WMWSDLEventHandler *StartElement(const wstring& wstrURI,
									const wstring& wstrLocalName,
									const wstring& wstrQualifiedName,
									WMXMLAttributeMap& mapAttributes,
									NSPrefixMap& mapNSPrefixes,
									WMXMLElement *pElement);
    void ReadAttributes(WMXMLAttributeMap& mapAttributes, NSPrefixMap& mapNSPrefixes);

	map <wstring, WMOperationHandler *>& GetOperationMap() { return m_mapOperations; }
	WMOperationHandler *GetOperation(const wstring& wstrOpName);

	void GetPortTypeNames(wstring& wstrTypeName, wstring& wstrTypeNS)
	{
		wstrTypeName = m_wstrType;
		wstrTypeNS = m_wstrTypeNS;
	}
	

protected:
	map <wstring, WMOperationHandler *>		m_mapOperations;
	wstring									m_wstrType;
	wstring									m_wstrTypeNS;
};

class WMPortHandler : public WMWSDLEventHandler  
{
public:
	WMPortHandler() {}
	virtual ~WMPortHandler() {}
    WMWSDLEventHandler *StartElement(const wstring& wstrURI,
									const wstring& wstrLocalName,
									const wstring& wstrQualifiedName,
									WMXMLAttributeMap& mapAttributes,
									NSPrefixMap& mapNSPrefixes,
									WMXMLElement *pElement)
	{ return IGNORE_ELEMENT_HANDLER; }

    void ReadAttributes(WMXMLAttributeMap& mapAttributes, NSPrefixMap& mapNSPrefixes);
	const wstring& GetBindingName() { return m_wstrBinding; }
	const wstring& GetBindingNS() { return m_wstrBindingNS; }

protected:
	wstring					m_wstrBinding;
	wstring					m_wstrBindingNS;
};

class WMServiceHandler : public WMWSDLEventHandler  
{
public:
	WMServiceHandler() {}
	virtual ~WMServiceHandler()
	{
		map<wstring, WMPortHandler *>::iterator iM;
		for (iM = m_mapPorts.begin();
			iM != m_mapPorts.end(); iM++)
		{
			delete (*iM).second;
		}
	}
    WMWSDLEventHandler *StartElement(const wstring& wstrURI,
									const wstring& wstrLocalName,
									const wstring& wstrQualifiedName,
									WMXMLAttributeMap& mapAttributes,
									NSPrefixMap& mapNSPrefixes,
									WMXMLElement *pElement);
	WMPortHandler *GetPort(const wstring& wstrPortName);
	map<wstring, WMPortHandler *>& GetPortMap() { return m_mapPorts; }

protected:
	map<wstring, WMPortHandler *>	m_mapPorts;
};

class WMDefinitionsHandler : public WMWSDLEventHandler  
{
public:
	WMDefinitionsHandler() {}
	virtual ~WMDefinitionsHandler()
	{
		map<wstring, WMBindingHandler *>::iterator iM1;
		for (iM1 = m_mapBindings.begin();
			iM1 != m_mapBindings.end(); iM1++)
		{
			delete (*iM1).second;
		}
		map<wstring, WMServiceHandler *>::iterator iM2;
		for (iM2 = m_mapServices.begin();
			iM2 != m_mapServices.end(); iM2++)
		{
			delete (*iM2).second;
		}
		map<wstring, WMMessageHandler *>::iterator iM3;
		for (iM3 = m_mapMessages.begin();
			iM3 != m_mapMessages.end(); iM3++)
		{
			delete (*iM3).second;
		}
		map<wstring, WMPortTypeHandler *>::iterator iM4;
		for (iM4 = m_mapPortTypes.begin();
			iM4 != m_mapPortTypes.end(); iM4++)
		{
			delete (*iM4).second;
		}
	}
    WMWSDLEventHandler *StartElement(const wstring& wstrURI,
										const wstring& wstrLocalName,
										const wstring& wstrQualifiedName,
										WMXMLAttributeMap& mapAttributes,
										NSPrefixMap& mapNSPrefixes,
										WMXMLElement *pElement);
    void ReadAttributes(WMXMLAttributeMap& mapAttributes, NSPrefixMap& mapNSPrefixes);
	const wstring& GetName() { return m_wstrName; }
	const wstring& GetTNS() { return m_wstrTNS; }

	WMServiceHandler *GetService(const wstring& wstrServiceName, const wstring& wstrNamespace);
	map<wstring, WMServiceHandler *>& GetServiceMap() { return m_mapServices; }

	WMPortTypeHandler *GetPortType(const wstring& wstrTypeName, const wstring& wstrNamespace);
	map<wstring, WMPortTypeHandler *>& GetPortTypeMap() { return m_mapPortTypes; }

	WMBindingHandler *GetBinding(   const wstring& wstrServiceName,
									const wstring& wstrPortName,
									const wstring& wstrNamespace);
	map<wstring, WMBindingHandler *>& GetBindingMap() { return m_mapBindings; }
	WMMessageHandler *GetMessage(const wstring& wstrMessageName,
									const wstring& wstrNamespace);
	map<wstring, WMMessageHandler *>& GetMessageMap() { return m_mapMessages; }
	WMTypesHandler& GetTypes() { return m_Types; }
	bool GetSchemaElemType( const wstring& wstrElemName,
							const wstring& wstrElemNS,
							wstring& wstrType,
							wstring& wstrTypeNS);

	bool GetArrayType(  const wstring& wstrArrayName,
						const wstring& wstrArrayNS,
						wstring& wstrType,
						wstring& wstrTypeNS);
	bool GetArrayTypeLit(   const wstring& wstrArrayName,
						    const wstring& wstrArrayNS,
						    wstring& wstrItemType,
						    wstring& wstrItemTypeNS,
                            wstring& wstrItemName,
                                wstring& wstrItemNS);
	bool GetArrayDims(  const wstring& wstrArrayName,
						const wstring& wstrArrayNS,
						unsigned int& nDims);
	bool GetSimpleBaseType(	const wstring& wstrName,
							const wstring& wstrNS,
							wstring& wstrBaseType,
							wstring& wstrBaseTypeNS);
	bool GetComplexBaseType(const wstring& wstrName,
							const wstring& wstrNS,
							wstring& wstrBaseType,
							wstring& wstrBaseTypeNS);
	WMSchemaSimpleTypeHandler *GetSimpleType(	const wstring& wstrName,
												const wstring& wstrNS);
	WMSchemaComplexTypeHandler *GetComplexType( const wstring& wstrName,
												const wstring& wstrNS);
	bool GetStructMemberType(   const wstring& wstrStructName,
								const wstring& wstrStructNS,
								const wstring& wstrMemberName,
								const wstring& wstrMemberNS,
								wstring& wstrType,
								wstring& wstrTypeNS);
	bool GetFirstStructMember(  const wstring& wstrStructName,
								const wstring& wstrStructNS,
								wstring& wstrMemberName,
								wstring& wstrMemberNS,
								wstring& wstrType,
								wstring& wstrTypeNS,
								long& lPosition);
	bool GetNextStructMember(   const wstring& wstrStructName,
								const wstring& wstrStructNS,
								wstring& wstrMemberName,
								wstring& wstrMemberNS,
								wstring& wstrType,
								wstring& wstrTypeNS,
								long& lPosition);

protected:

	map<wstring, WMMessageHandler *>	m_mapMessages;
	map<wstring, WMPortTypeHandler *>	m_mapPortTypes;
	map<wstring, WMBindingHandler *>	m_mapBindings;
	map<wstring, WMServiceHandler *>	m_mapServices;
	WMTypesHandler						m_Types;
	wstring								m_wstrName;
	wstring								m_wstrTNS;
};

class WMWSDLDesc : public WMWSDLEventHandler  
{
public:
	WMWSDLDesc() {}
	virtual ~WMWSDLDesc() {}
    WMWSDLEventHandler *StartElement(const wstring& wstrURI,
									const wstring& wstrLocalName,
									const wstring& wstrQualifiedName,
									WMXMLAttributeMap& mapAttributes,
									NSPrefixMap& mapNSPrefixes,
									WMXMLElement *pElement);
	// query support
	const wstring& GetDefinitionsName() { return m_Definitions.GetName(); }
	const wstring& GetDefinitionsTNS() { return m_Definitions.GetTNS(); }
	WMDefinitionsHandler& GetDefinitions() { return m_Definitions; }

protected:
	WMDefinitionsHandler	m_Definitions;
};


#endif // !defined(AFX_WMWSDLELEMENTS_H__56FAC337_D136_4FA3_AC7B_F229F23D2566__INCLUDED_)
