#pragma once

#include "RsVector.h"

#ifndef RS_SELECTIONHELPER_H_INCLUDED
#define RS_SELECTIONHELPER_H_INCLUDED

#define NODELIST_SEPARATOR wchar_t(59)

/**
Selection helper is a set of static methods that help to make it easier to use the selections.
This file does not include any headers to preserve the independency and user is required to include all files
*/
namespace RsSelectionHelper {
    using namespace ATL;

    /**
    This method returns the package specified by the GUID
    @param _KernelProvider specifies the class that provides static public method GetKernelPackage
    @param _PackageClass specifies the class whose UUID can be used to perform the search
    @param _OutInterface specifies the output interface returned by the method
    */
    template <class _KernelProvider, class _PackageClass, class _OutInterface>
    static HRESULT GetPackage(_OutInterface** ppPackage)
    {
        ATLASSERT(ppPackage);
        if (!ppPackage)
            return E_INVALIDARG;
        *ppPackage = NULL;
        CComPtr<IRpKernel> spKernelPackage;
        _KernelProvider::GetKernelPackage(&spKernelPackage);
        CComPtr<IRsUnknownPackage> spPackage;
        if (spKernelPackage)
            spKernelPackage->FindPackage(__uuidof(_PackageClass), &spPackage);
        CComQIPtr<_OutInterface> spOutPackage = spPackage;
        ATLASSERT((spOutPackage) || (!"Package cannot be found"));
        if (!spOutPackage)
            return E_FAIL;
        return spOutPackage.CopyTo(ppPackage);
    }

    /**
    This method returns the selection manager and performs all tasks like package search and others
    @param _KernelProvider specifies the class that provides static public method GetKernelPackage
    */
    template <class _KernelProvider>
    static HRESULT GetSelectionManager(IRsSelectionManager** ppSelMng)
    {
        ATLASSERT(ppSelMng);
        if (!ppSelMng)
            return E_INVALIDARG;
        *ppSelMng = NULL;
        CComQIPtr<IRpKernel> spKernel;
        RsSelectionHelper::GetPackage<_KernelProvider, CRpKernel, IRpKernel>(&spKernel);
        ATLASSERT(spKernel || (!"Kernel package cannot be found"));
        if (!spKernel)
            return E_FAIL;
        return spKernel->GetSelectionManager(ppSelMng);
    }

	/**
	This method checks if node is in kernel space (not deleted)
	@param spInput specifies node to test
	*/
	template <class _KernelProvider>
	static bool IsNodeDeleted(IRsNode *pNode)
	{

		CComQIPtr<IRsBaseNode> spBase = pNode;
		while (spBase) {
			CComPtr<IRsNode> spOwner;
			spBase->GetOwner(&spOwner);
			CComQIPtr<IRnKernel> spKernel = spOwner;
			if (spKernel)
				return false;
			spBase = spOwner;
		};
		return true;
	}

    /**
    This method returns the registered node selection. 
    @param _KernelProvider specifies the class that provides static public method GetKernelPackage
    @param ppSelection is filled with the selection (existing or new)
    @param pNotify specifies the optional notification interface
    */
    template <class _KernelProvider>
    static HRESULT GetNodeSelection(IRdSelNodeSelection** ppSelection,
                                    IRsSelectionNotification *pNotify = NULL)
    {
        ATLASSERT(ppSelection);
        if (!ppSelection)
            return E_INVALIDARG;
        *ppSelection = NULL;
        //ATLASSERT(!"This is an untested code. Test it and then remove the assert");
        CComQIPtr<IRpKernel> spKernel;
        RsSelectionHelper::GetPackage<_KernelProvider, CRpKernel, IRpKernel>(&spKernel);
        ATLASSERT(spKernel || (!"Kernel package cannot be found"));
        if (!spKernel)
            return E_FAIL;
        return spKernel->GetNodeSelection(pNotify, ppSelection);
    }

    /**
    This method can register / unregister the selection notification
    @param _KernelProvider specifies the class that provides static public method GetKernelPackage
    @param SelectionID specifies the ID of the selection notification
    @param pNotify specifies notifier obect
    @param bRegister TRUE will register notification, FALSE will unregister notification
    */
    template <class _KernelProvider>
    static HRESULT NotifyChange(const GUID &SelectionID, IRsSelectionNotification *pNotify, BOOL bRegister = TRUE)
    {
        ATLASSERT(pNotify);
        if (!pNotify)
            return E_INVALIDARG;
        CComPtr<IRsSelectionManager> spSelMng;
        RsSelectionHelper::GetSelectionManager<_KernelProvider>(&spSelMng);
        ATLASSERT(spSelMng || (!"Selection manager cannot be found"));
        if (!spSelMng)
            return E_FAIL;
        if (bRegister)
            return spSelMng->RegisterNotification(SelectionID, pNotify);
        else
            return spSelMng->UnregisterNotification(SelectionID, pNotify);
    }

    /**
    This method returns arbitrary registered selection that can be created using standard dataobject factories.
    @param _KernelProvider specifies the class that provides static public method GetKernelPackage
    @param _DataObject specifies the dataobject identifier used in the call to dataobject factory
    @param _OutInterface specifies the output interface pointer of the method.
    @param SelectionID specifies the ID of the selection
    @param ppSelection is filled with the selection (existing or new)
    @param pNotify specifies the optional notification interface
    */
    template <class _KernelProvider, class _DataObject, class _OutInterface>
    static HRESULT GetSelection(const GUID SelectionID, _OutInterface** ppSelection, 
                                IRsSelectionNotification *pNotify = NULL)
    {
        //ATLASSERT(!"This is an untested code. Test it and then remove the assert");
        HRESULT hRes = S_OK;

        CComPtr<IRsSelectionManager> spSelMng;
		RsSelectionHelper::GetSelectionManager<_KernelProvider>(&spSelMng);
        ATLASSERT(spSelMng || (!"Selection manager cannot be found"));
        if (!spSelMng)
            return E_FAIL;
        if (pNotify)
        {
            hRes = spSelMng->RegisterNotification(SelectionID, pNotify);
            if (FAILED(hRes))
                return hRes;
        }
        spSelMng->LockObject();
        CComQIPtr<IRsBaseSelection> spBaseSelection;
        spSelMng->GetSelection(SelectionID, &spBaseSelection);
        CComQIPtr<_OutInterface> spHasOriginalSelection = spBaseSelection;
        if (!spHasOriginalSelection)
        {
            CComPtr<IRpKernel>      spKernelPackage;
            _KernelProvider::GetKernelPackage(&spKernelPackage);
            CComPtr<IRsSysFactory>	spFactory;
            if (spKernelPackage)
                spKernelPackage->GetSysFactory(&spFactory);
            CComPtr<IRsDataObject>  spData;
            if (spFactory)
                spFactory->CreateDataObj(&__uuidof(_DataObject), &spData);
            spBaseSelection = spData;
            if (spBaseSelection)
                spHasOriginalSelection = spData;
            if (spBaseSelection)
			{
				spBaseSelection->Initialize(SelectionID, spSelMng);
                hRes = spSelMng->SetSelection(SelectionID, spBaseSelection);
			}
        }
        if (!spHasOriginalSelection)
            hRes = E_NOINTERFACE;
        spHasOriginalSelection.CopyTo(ppSelection);
        spSelMng->UnlockObject();
        return hRes;
    }

    /**
    This method returns the first selected node if any.
    @param _KernelProvider specifies the class that provides static public method GetKernelPackage
    @param pNode is filled with the selected node. NULL is there if there is no selected node
    */
    template <class _KernelProvider>
    static HRESULT GetFirstSelectedNode(IRsNode **pNode)
    {
        ATLASSERT(pNode);
        if (!pNode)
            return E_INVALIDARG;
        //ATLASSERT(!"This is an untested code. Test it and then remove the assert");
        CComQIPtr<IRdSelNodeSelection> spNodeSelection;
        RsSelectionHelper::GetNodeSelection<_KernelProvider>(&spNodeSelection);
        CComPtr<IRsNode> spNode;
        if ((spNodeSelection) && (!spNodeSelection->IsEmpty()))
            spNodeSelection->GetAt(0, &spNode);
        return spNode.CopyTo(pNode);
    }

    /**
    This method returns the name of the first selected node if any.
    @param _KernelProvider specifies the class that provides static public method GetKernelPackage
    @param bsName is filled with the selected node name. Empty string is there if there is no selected node
    */
    template <class _KernelProvider>
    static HRESULT GetFirstSelectedNodeName(BSTR *bsName)
    {
        ATLASSERT(bsName);
        if (!bsName)
            return E_INVALIDARG;
        //ATLASSERT(!"This is an untested code. Test it and then remove the assert");
        CComQIPtr<IRdSelNodeSelection> spNodeSelection;
        RsSelectionHelper::GetNodeSelection<_KernelProvider>(&spNodeSelection);
        CComPtr<IRsNode> spNode;
        if ((spNodeSelection) && (!spNodeSelection->IsEmpty()))
            spNodeSelection->GetAt(0, &spNode);
        CComBSTR bsFullName;
        CComQIPtr<IRsBaseNode> spBaseNode = spNode;
        if (spBaseNode)
            spBaseNode->GetFullName(NULL, &bsFullName);
        return bsFullName.CopyTo(bsName);
    }

    /**
    This method selects a node (it is a replacement for the RnKernel->Select() method).
    @param _KernelProvider specifies the class that provides static public method GetKernelPackage
    @param pNode specifies the node to select
    @param bReplace specifies the operation. TRUE means that current selection is replaced by the new one and FALSE means that selections are merged
    */
    template <class _KernelProvider>
    static HRESULT SelectNode(IRsNode *pNode, BOOL bReplace)
    {
        ATLASSERT(pNode);
        if (!pNode)
            return E_INVALIDARG;
        //ATLASSERT(!"This is an untested code. Test it and then remove the assert");
        CComQIPtr<IRdSelNodeSelection> spNodeSelection;
        RsSelectionHelper::GetNodeSelection<_KernelProvider>(&spNodeSelection);
        if (!spNodeSelection)
            return E_FAIL;
        if (bReplace)
            return spNodeSelection->ReplaceBy(pNode);
        else
            return spNodeSelection->Add(pNode);
    }

    /**
    This method deselects a node.
    @param _KernelProvider specifies the class that provides static public method GetKernelPackage
    @param pNode specifies the node to deselect
    */
    template <class _KernelProvider>
    static HRESULT DeselectNode(IRsNode *pNode)
    {
        ATLASSERT(pNode);
        if (!pNode)
            return E_INVALIDARG;
        //ATLASSERT(!"This is an untested code. Test it and then remove the assert");
        CComQIPtr<IRdSelNodeSelection> spNodeSelection;
        RsSelectionHelper::GetNodeSelection<_KernelProvider>(&spNodeSelection);
        if (!spNodeSelection)
            return E_FAIL;
        return spNodeSelection->Remove(pNode);
    }

	/**
	Method clears selection.
	@param _KernelProvider specifies the class that provides static public method GetKernelPackage
	*/
	template <class _KernelProvider>
	static HRESULT DeselectAll()
	{
		CComQIPtr<IRdSelNodeSelection> spNodeSelection;
		RsSelectionHelper::GetNodeSelection<_KernelProvider>(&spNodeSelection);
		if (!spNodeSelection)
			return E_FAIL;
		return spNodeSelection->RemoveAll();
	}

    /**
    This method checks whether a node is selected. S_FALSE result means the node is not selected.
    @param _KernelProvider specifies the class that provides static public method GetKernelPackage
    @param pNode specifies the node to check
    */
    template <class _KernelProvider>
    static HRESULT IsSelected(IRsNode *pNode)
    {
        ATLASSERT(pNode);
        if (!pNode)
            return E_INVALIDARG;
        //ATLASSERT(!"This is an untested code. Test it and then remove the assert");
        CComQIPtr<IRdSelNodeSelection> spNodeSelection;
        RsSelectionHelper::GetNodeSelection<_KernelProvider>(&spNodeSelection);
        if (!spNodeSelection)
            return E_FAIL;
        return spNodeSelection->IsInSelection(pNode);
    }

	/**
    This method selects node list
    @param _KernelProvider specifies the class that provides static public method GetKernelPackage
    @param pNode specifies the nodes to select
    @param dwCount specifies the node array
    @param bReplace specifies the operation. TRUE means that current selection is replaced by the new one and FALSE means that selections are merged
    */
    template <class _KernelProvider>
    static HRESULT SelectNodeList(IRsNode **pNode, DWORD dwCount, BOOL bReplace)
    {
        ATLASSERT(pNode);
        if (!pNode)
            return E_INVALIDARG;
        //ATLASSERT(!"This is an untested code. Test it and then remove the assert");
        CComQIPtr<IRdSelNodeSelection> spNodeSelection;
        RsSelectionHelper::GetNodeSelection<_KernelProvider>(&spNodeSelection);
        CComPtr<IRsNode> spNode;
        if (!spNodeSelection)
            return E_FAIL;
        if (bReplace)
            return spNodeSelection->ReplaceByArray(dwCount, pNode);
        else
            return spNodeSelection->AddArray(dwCount, pNode);
    }

	/**
    This method selects node list
    @param _KernelProvider specifies the class that provides static public method GetKernelPackage
    @param _InInterface specifies the interface of the 
    @param spInput specifies the node array to select
    @param bReplace specifies the operation. TRUE means that current selection is replaced by the new one and FALSE means that selections are merged
    */
    template <class _KernelProvider>
    static HRESULT SelectNodeArray(const CInterfaceArray<IRsNode> &spInput, BOOL bReplace)
    {
        //ATLASSERT(!"This is an untested code. Test it and then remove the assert");
        CComQIPtr<IRdSelNodeSelection> spNodeSelection;
        RsSelectionHelper::GetNodeSelection<_KernelProvider>(&spNodeSelection);
        CComPtr<IRsNode> spNode;
        if (!spNodeSelection)
            return E_FAIL;
        if (bReplace)
            return spNodeSelection->ReplaceByArray((DWORD)spInput.GetCount(), (IRsNode**)spInput.GetData());
        else
            return spNodeSelection->AddArray((DWORD)spInput.GetCount(), (IRsNode**)spInput.GetData());
    }

    /**
    This method selects node list
    @param _KernelProvider specifies the class that provides static public method GetKernelPackage
    @param pNode specifies the nodes to select
    @param dwCount specifies the node array
    @param bReplace specifies the operation. TRUE means that current selection is replaced by the new one and FALSE means that selections are merged
    */
    template <class _KernelProvider>
    static HRESULT SelectNodeObjectList(IRsObjectList *pSelection, BOOL bReplace)
    {
        ATLASSERT(pSelection);
        if (!pSelection)
            return E_INVALIDARG;
        //ATLASSERT(!"This is an untested code. Test it and then remove the assert");
        CComQIPtr<IRdSelNodeSelection> spNodeSelection;
        RsSelectionHelper::GetNodeSelection<_KernelProvider>(&spNodeSelection);
        CComPtr<IRsNode> spNode;
        if (!spNodeSelection)
            return E_FAIL;
        CInterfaceArray<IRsNode> spInput;
        RtUlong uSize = 0;
        pSelection->GetCount(&uSize);
        for (RtUlong i=0; i<uSize; i++)
        {
            CComPtr<IRsObject> spObj;
            pSelection->GetAt(i, &spObj);
            CComQIPtr<IRsNode> spNode = spObj;
            if (spNode)
                spInput.Add(spNode);
        }
        return RsSelectionHelper::SelectNodeArray<_KernelProvider>(spInput, bReplace);
    }


	/**
	This method selects node list
	@param _KernelProvider specifies the class that provides static public method GetKernelPackage
	@param szSelection packed list of nodes
	@param bReplace specifies the operation. TRUE means that current selection is replaced by the new one and FALSE means that selections are merged
	*/
	template <class _KernelProvider>
	static HRESULT SelectNodePackedList(BSTR szSelection, BOOL bReplace)
	{
		CComPtr<IRsObjectList> spObjectList;
		UnpackSelectionList<_KernelProvider>(szSelection,&spObjectList);
		return SelectNodeObjectList<_KernelProvider>(spObjectList,bReplace);
	};
		

    /**
    This method returns the selection as an old CRsObjectList class.
    @param _KernelProvider specifies the class that provides static public method GetKernelPackage
    @param pSelection is filled with the new selection.
    */
    template <class _KernelProvider>
    static HRESULT GetSelectedNodes(IRsObjectList **pSelection)
    {
        ATLASSERT(pSelection);
        if (!pSelection)
            return E_INVALIDARG;
        //ATLASSERT(!"This is an untested code. Test it and then remove the assert");
        CComQIPtr<IRdSelNodeSelection> spNodeSelection;
        RsSelectionHelper::GetNodeSelection<_KernelProvider>(&spNodeSelection);

        CComPtr<IRpKernel> spKernelPackage;
        _KernelProvider::GetKernelPackage(&spKernelPackage);
        CComPtr<IRsKernelFactory> spFactory;
        HRESULT hr;
        if (FAILED(hr = spKernelPackage->GetKernelFactory(&spFactory)))
            return hr;

        CComPtr<IRsObjectList> spSelection;
        if (FAILED(hr = spFactory->CreateObjectList(&spSelection)))
            return hr;

        if (spNodeSelection)
        {
            spNodeSelection->LockObject();
            for (RtUlong i=0; i<spNodeSelection->GetCount(); i++)
            {
                CComPtr<IRsNode> spNode;
                spNodeSelection->GetAt(i, &spNode);
				CComQIPtr<IRsObject>   spObject = spNode;
                if (spObject)
                    spSelection->Add(spObject);
            }
            spNodeSelection->UnlockObject();
        }
        return spSelection.CopyTo(pSelection);
    }

	/**
	This method returns the selection as an CRsObjectList class. Deleted nodes are removed from 
	selection.

	@param _KernelProvider specifies the class that provides static public method GetKernelPackage
	@param pSelection is filled with the new selection.
	*/
	template <class _KernelProvider>
	static HRESULT GetActiveSelectedNodes(IRsObjectList **pSelection)
	{
		ATLASSERT(pSelection);
		if (!pSelection)
			return E_INVALIDARG;
		//ATLASSERT(!"This is an untested code. Test it and then remove the assert");
		CComQIPtr<IRdSelNodeSelection> spNodeSelection;
		RsSelectionHelper::GetNodeSelection<_KernelProvider>(&spNodeSelection);

		CComPtr<IRpKernel> spKernelPackage;
		_KernelProvider::GetKernelPackage(&spKernelPackage);
		CComPtr<IRsKernelFactory> spFactory;
		HRESULT hr;
		if (FAILED(hr = spKernelPackage->GetKernelFactory(&spFactory)))
			return hr;

		CComPtr<IRsObjectList> spSelection;
		if (FAILED(hr = spFactory->CreateObjectList(&spSelection)))
			return hr;

		if (spNodeSelection)
		{
			spNodeSelection->LockObject();
			for (RtUlong i=0; i<spNodeSelection->GetCount(); i++)
			{
				CComPtr<IRsNode> spNode;
				spNodeSelection->GetAt(i, &spNode);
				if (IsNodeDeleted<_KernelProvider>(spNode))
					continue;

				CComQIPtr<IRsObject> spObject = spNode;
				if (spObject)
					spSelection->Add(spObject);
			}
			spNodeSelection->UnlockObject();
		}
		return spSelection.CopyTo(pSelection);
	}


    /**
    This method returns the selection as an old CRsObjectList class.
    @param _KernelProvider specifies the class that provides static public method GetKernelPackage
    @param _OutInterface specifies the interface
    @param spOutArray is filled with the selected nodes. Note that array is not cleared inside the method
    */
    template <class _KernelProvider, class _OutInterface>
    static HRESULT GetSelectedNodesArray(CInterfaceArray<_OutInterface> &spOutArray)
    {
        //ATLASSERT(!"This is an untested code. Test it and then remove the assert");
        CComQIPtr<IRdSelNodeSelection> spNodeSelection;
        RsSelectionHelper::GetNodeSelection<_KernelProvider>(&spNodeSelection);
        if (spNodeSelection)
        {
            spNodeSelection->LockObject();
            for (RtUlong i=0; i<spNodeSelection->GetCount(); i++)
            {
                CComPtr<IRsNode> spNode;
                spNodeSelection->GetAt(i, &spNode);
                CComQIPtr<_OutInterface> spOutNode = spNode;
                if (spOutNode)
                    spOutArray.Add(spOutNode);
            }
            spNodeSelection->UnlockObject();
        }
        return S_OK;
    }


	/**
	Get selection list provided by parameter. If parameter is "", current selection is used. Else parameter is
	decomposed into object list elements.

	@param _KernelProvider specifies the class that provides static public method GetKernelPackage
	@param pObjList returned selection list
	*/
	template <class _KernelProvider>
	HRESULT GetSelectionList(VARIANT vtIn, IRsObjectList **pObjList) 
	{
		CComVariant v(vtIn);
		CComBSTR l;
		if (v.ChangeType(VT_BSTR) == S_OK) {
			l = v.bstrVal;
		};

		if (l != L"") {
			return UnpackSelectionList<_KernelProvider>(l,pObjList);
		}
		else {
			return RsSelectionHelper::GetSelectedNodes<_KernelProvider>(pObjList);
		};
	};

	

	/**
	Get list of selected object from list of objects packed in a string.

	@param _KernelProvider specifies the class that provides static public method GetKernelPackage
	@param szList list of packed objects
	@param pObjList returned selection list
	*/
	template <class _KernelProvider>
	HRESULT UnpackSelectionList(CComBSTR l, IRsObjectList **pObjList) 
	{
		CComPtr<IRsObjectList> spObjList;

		HRESULT hRes;

		CComPtr<IRpKernel> spKernel;
		_KernelProvider::GetKernelPackage(&spKernel);

		CComPtr<IRsKernelFactory> spFactory;
		if (FAILED(hRes = spKernel->GetKernelFactory(&spFactory)))
			return hRes;
		if(FAILED(hRes = spFactory->CreateObjectList(&spObjList)))
			return hRes;

		CComPtr<IRnKernel> spKernelNode;
		spKernel->GetKernelNode(&spKernelNode);
		CComQIPtr<IRnEncapsulator> spKernelEnc = spKernelNode;

		RtUlong lng = l.Length();
		if (lng > 0) {
			wchar_t *tmp = (wchar_t*)malloc(sizeof(wchar_t)*lng);
			RtUlong ptr = 0;
			RtUlong i;
			for (i = 0; i<lng;i++) {
				if (l.m_str[i] == NODELIST_SEPARATOR) {
					CComBSTR name(ptr,tmp);

					CComPtr<IRsNode> node;
					spKernelEnc->FindNodeByName(name,&node);
					CComQIPtr<IRsObject>   spObject = node;
					if (spObject) 
						spObjList->Add(spObject);
					ptr = 0;
				}
				else {
					tmp[ptr++] = l.m_str[i];
				};
			};
			CComBSTR name(ptr,tmp);

			CComPtr<IRsNode> node;
			spKernelEnc->FindNodeByName(name,&node);
			CComQIPtr<IRsObject>   spObject = node;
			if (spObject) spObjList->Add(spObject);
			free(tmp);
		};

		spObjList.CopyTo(pObjList);
		return S_OK;
	};

	/**
	Pack selection list to single string. 

	@param _KernelProvider specifies the class that provides static public method GetKernelPackage
	@param pObjList list of selected objects
	@param pszSelection returned selection string
	*/
	template <class _KernelProvider>
	HRESULT PackSelectionList(IRsObjectList *pObjList,BSTR *pszSelection) 
	{
		CComBSTR result;
		RtUlong cnt;
		pObjList->GetCount(&cnt);
		if (!cnt) {
			return result.CopyTo(pszSelection);
		}
		else {
			CComQIPtr<IRsBaseNode> spBase;
			for (RtUlong i = 0; i<cnt;i++) {
				CComBSTR szName;
				CComPtr<IRsObject> spObj;
				pObjList->GetAt(i,&spObj);
				spBase = spObj;
				if (!spBase)
					continue;

				spBase->GetFullName(NULL,&szName);
				if (result) {
					result.Append(NODELIST_SEPARATOR);
				};
				result.Append(szName);
			};
			return result.CopyTo(pszSelection);
		};
	};

	/**
	Pack selection list to single string. 

	@param _KernelProvider specifies the class that provides static public method GetKernelPackage
	@param aNodes list of nodes
	@param pszSelection returned selection string
	*/
	template <class _KernelProvider>
	HRESULT PackSelectionList(RsVector< CComPtr<IRsNode> > &aNodes,BSTR *pszSelection) 
	{
		CComBSTR result;
		RtUlong cnt;
		cnt = aNodes.size();
		if (!cnt) {
			return result.CopyTo(pszSelection);
		}
		else {
			CComQIPtr<IRsBaseNode> spBase;
			for (RtUlong i = 0; i<cnt;i++) {
				CComBSTR szName;
				spBase = aNodes[i];
				if (!spBase)
					continue;

				spBase->GetFullName(NULL,&szName);
				if (result) {
					result.Append(NODELIST_SEPARATOR);
				};
				result.Append(szName);
			};
			return result.CopyTo(pszSelection);
		};
	};


}

#endif //RS_SELECTIONHELPER_H_INCLUDED
