/*
 * CompositeMonikers implementation
 *
 * Copyright 1999  Noomen Hamza
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <assert.h>
#include <stdarg.h>
#include <string.h>

#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winerror.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "ole2.h"
#include "moniker.h"

WINE_DEFAULT_DEBUG_CHANNEL(ole);

static const CLSID CLSID_CompositeMoniker = {
  0x309, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46}
};

#define  BLOCK_TAB_SIZE 5 /* represent the first size table and it's increment block size */

/* CompositeMoniker data structure */
typedef struct CompositeMonikerImpl{

    const IMonikerVtbl*  lpvtbl1;  /* VTable relative to the IMoniker interface.*/

    /* The ROT (RunningObjectTable implementation) uses the IROTData
     * interface to test whether two monikers are equal. That's why IROTData
     * interface is implemented by monikers.
     */
    const IROTDataVtbl*  lpvtbl2;  /* VTable relative to the IROTData interface.*/

    LONG ref; /* reference counter for this object */

    IMoniker** tabMoniker; /* dynamaic table containing all components (monikers) of this composite moniker */

    ULONG    tabSize;      /* size of tabMoniker */

    ULONG    tabLastIndex;  /* first free index in tabMoniker */

} CompositeMonikerImpl;


/* EnumMoniker data structure */
typedef struct EnumMonikerImpl{

    const IEnumMonikerVtbl *lpVtbl;  /* VTable relative to the IEnumMoniker interface.*/

    LONG ref; /* reference counter for this object */

    IMoniker** tabMoniker; /* dynamic table containing the enumerated monikers */

    ULONG      tabSize; /* size of tabMoniker */

    ULONG      currentPos;  /* index pointer on the current moniker */

} EnumMonikerImpl;

static inline IMoniker *impl_from_IROTData( IROTData *iface )
{
    return (IMoniker *)((char*)iface - FIELD_OFFSET(CompositeMonikerImpl, lpvtbl2));
}

static HRESULT EnumMonikerImpl_CreateEnumMoniker(IMoniker** tabMoniker,ULONG tabSize,ULONG currentPos,BOOL leftToRigth,IEnumMoniker ** ppmk);

/*******************************************************************************
 *        CompositeMoniker_QueryInterface
 *******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
{
    CompositeMonikerImpl *This = (CompositeMonikerImpl *)iface;

    TRACE("(%p,%p,%p)\n",This,riid,ppvObject);

    /* Perform a sanity check on the parameters.*/
    if ( (This==0) || (ppvObject==0) )
	return E_INVALIDARG;

    /* Initialize the return parameter */
    *ppvObject = 0;

    /* Compare the riid with the interface IDs implemented by this object.*/
    if (IsEqualIID(&IID_IUnknown, riid) ||
        IsEqualIID(&IID_IPersist, riid) ||
        IsEqualIID(&IID_IPersistStream, riid) ||
        IsEqualIID(&IID_IMoniker, riid)
       )
        *ppvObject = iface;
    else if (IsEqualIID(&IID_IROTData, riid))
        *ppvObject = (IROTData*)&(This->lpvtbl2);

    /* Check that we obtained an interface.*/
    if ((*ppvObject)==0)
        return E_NOINTERFACE;

    /* Query Interface always increases the reference count by one when it is successful */
    IMoniker_AddRef(iface);

    return S_OK;
}

/******************************************************************************
 *        CompositeMoniker_AddRef
 ******************************************************************************/
static ULONG WINAPI
CompositeMonikerImpl_AddRef(IMoniker* iface)
{
    CompositeMonikerImpl *This = (CompositeMonikerImpl *)iface;

    TRACE("(%p)\n",This);

    return InterlockedIncrement(&This->ref);
}

/******************************************************************************
 *        CompositeMoniker_Release
 ******************************************************************************/
static ULONG WINAPI
CompositeMonikerImpl_Release(IMoniker* iface)
{
    CompositeMonikerImpl *This = (CompositeMonikerImpl *)iface;
    ULONG i;
    ULONG ref;

    TRACE("(%p)\n",This);

    ref = InterlockedDecrement(&This->ref);

    /* destroy the object if there's no more reference on it */
    if (ref == 0){

        /* release all the components before destroying this object */
        for (i=0;i<This->tabLastIndex;i++)
            IMoniker_Release(This->tabMoniker[i]);

        HeapFree(GetProcessHeap(),0,This->tabMoniker);
        HeapFree(GetProcessHeap(),0,This);
    }
    return ref;
}

/******************************************************************************
 *        CompositeMoniker_GetClassID
 ******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)
{
    TRACE("(%p,%p),stub!\n",iface,pClassID);

    if (pClassID==NULL)
        return E_POINTER;

    *pClassID = CLSID_CompositeMoniker;

    return S_OK;
}

/******************************************************************************
 *        CompositeMoniker_IsDirty
 ******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_IsDirty(IMoniker* iface)
{
    /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
       method in the OLE-provided moniker interfaces always return S_FALSE because
       their internal state never changes. */

    TRACE("(%p)\n",iface);

    return S_FALSE;
}

/******************************************************************************
 *        CompositeMoniker_Load
 ******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_Load(IMoniker* iface,IStream* pStm)
{
    HRESULT res;
    DWORD constant;
    CLSID clsid;
    WCHAR string[1]={0};

    CompositeMonikerImpl *This = (CompositeMonikerImpl *)iface;

    TRACE("(%p,%p)\n",iface,pStm);

    /* this function call OleLoadFromStream function for each moniker within this object */

    /* read the a constant written by CompositeMonikerImpl_Save (see CompositeMonikerImpl_Save for more details)*/
    res=IStream_Read(pStm,&constant,sizeof(DWORD),NULL);

    if (SUCCEEDED(res)&& constant!=3)
        return E_FAIL;

    while(1){
#if 0
        res=OleLoadFromStream(pStm,&IID_IMoniker,(void**)&This->tabMoniker[This->tabLastIndex]);
#endif
        res=ReadClassStm(pStm,&clsid);
        DPRINTF("res=%ld",res);
        if (FAILED(res))
            break;

        if (IsEqualIID(&clsid,&CLSID_FileMoniker)){
            res=CreateFileMoniker(string,&This->tabMoniker[This->tabLastIndex]);
            if (FAILED(res))
                break;
            res=IMoniker_Load(This->tabMoniker[This->tabLastIndex],pStm);
            if (FAILED(res))
                break;
        }
        else if (IsEqualIID(&clsid,&CLSID_ItemMoniker)){
            CreateItemMoniker(string,string,&This->tabMoniker[This->tabLastIndex]);
            if (res!=S_OK)
                break;
            IMoniker_Load(This->tabMoniker[This->tabLastIndex],pStm);
            if (FAILED(res))
                break;
        }
        else if (IsEqualIID(&clsid,&CLSID_AntiMoniker)){
            CreateAntiMoniker(&This->tabMoniker[This->tabLastIndex]);
            if (FAILED(res))
                break;
            IMoniker_Load(This->tabMoniker[This->tabLastIndex],pStm);
            if (FAILED(res))
                break;
        }
        else if (IsEqualIID(&clsid,&CLSID_CompositeMoniker))
            return E_FAIL;

        else
        {
            FIXME("()\n");
            /* FIXME: To whoever wrote this code: It's either return or break. it cannot be both! */
            break;
            return E_NOTIMPL;
        }

        /* resize the table if needed */
        if (++This->tabLastIndex==This->tabSize){

            This->tabSize+=BLOCK_TAB_SIZE;
            This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(IMoniker));

            if (This->tabMoniker==NULL)
            return E_OUTOFMEMORY;
        }
    }

    return res;
}

/******************************************************************************
 *        CompositeMoniker_Save
 ******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_Save(IMoniker* iface,IStream* pStm,BOOL fClearDirty)
{
    HRESULT res;
    IEnumMoniker *enumMk;
    IMoniker *pmk;
    DWORD constant=3;

    TRACE("(%p,%p,%d)\n",iface,pStm,fClearDirty);

    /* This function calls OleSaveToStream function for each moniker within
     * this object.
     * When I tested this function in windows, I usually found this constant
     * at the beginning of the stream. I don't known why (there's no
     * indication in the specification) !
     */
    res=IStream_Write(pStm,&constant,sizeof(constant),NULL);

    IMoniker_Enum(iface,TRUE,&enumMk);

    while(IEnumMoniker_Next(enumMk,1,&pmk,NULL)==S_OK){

        res=OleSaveToStream((IPersistStream*)pmk,pStm);

        IMoniker_Release(pmk);

        if (FAILED(res)){

            IEnumMoniker_Release(pmk);
            return res;
        }
    }

    IEnumMoniker_Release(enumMk);

    return S_OK;
}

/******************************************************************************
 *        CompositeMoniker_GetSizeMax
 ******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_GetSizeMax(IMoniker* iface,ULARGE_INTEGER* pcbSize)
{
    IEnumMoniker *enumMk;
    IMoniker *pmk;
    ULARGE_INTEGER ptmpSize;

    /* The sizeMax of this object is calculated by calling  GetSizeMax on
     * each moniker within this object then summing all returned values
     */

    TRACE("(%p,%p)\n",iface,pcbSize);

    if (pcbSize!=NULL)
        return E_POINTER;

    pcbSize->u.LowPart =0;
    pcbSize->u.HighPart=0;

    IMoniker_Enum(iface,TRUE,&enumMk);

    while(IEnumMoniker_Next(enumMk,1,&pmk,NULL)){

        IMoniker_GetSizeMax(pmk,&ptmpSize);

        IMoniker_Release(pmk);

        pcbSize->u.LowPart +=ptmpSize.u.LowPart;
        pcbSize->u.HighPart+=ptmpSize.u.HighPart;
    }

    IEnumMoniker_Release(enumMk);

    return S_OK;
}

/******************************************************************************
 *                  CompositeMoniker_BindToObject
 ******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_BindToObject(IMoniker* iface, IBindCtx* pbc,
               IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult)
{
    HRESULT   res;
    IRunningObjectTable *prot;
    IMoniker *tempMk,*antiMk,*mostRigthMk;
    IEnumMoniker *enumMoniker;

    TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);

    if (ppvResult==NULL)
        return E_POINTER;

    *ppvResult=0;
    /* If pmkToLeft is NULL, this method looks for the moniker in the ROT, and if found, queries the retrieved */
    /* object for the requested interface pointer. */
    if(pmkToLeft==NULL){

        res=IBindCtx_GetRunningObjectTable(pbc,&prot);

        if (SUCCEEDED(res)){

            /* if the requested class was loaded before ! we don't need to reload it */
            res = IRunningObjectTable_GetObject(prot,iface,(IUnknown**)ppvResult);

            if (res==S_OK)
                return res;
        }
    }
    else{
        /* If pmkToLeft is not NULL, the method recursively calls IMoniker::BindToObject on the rightmost */
        /* component of the composite, passing the rest of the composite as the pmkToLeft parameter for that call */

        IMoniker_Enum(iface,FALSE,&enumMoniker);
        IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
        IEnumMoniker_Release(enumMoniker);

        res=CreateAntiMoniker(&antiMk);
        res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
        IMoniker_Release(antiMk);

        res=CompositeMonikerImpl_BindToObject(mostRigthMk,pbc,tempMk,riid,ppvResult);

        IMoniker_Release(tempMk);
        IMoniker_Release(mostRigthMk);
    }

    return res;
}

/******************************************************************************
 *        CompositeMoniker_BindToStorage
 ******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_BindToStorage(IMoniker* iface, IBindCtx* pbc,
               IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult)
{
    HRESULT   res;
    IMoniker *tempMk,*antiMk,*mostRigthMk;
    IEnumMoniker *enumMoniker;

    TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);

    *ppvResult=0;

    /* This method recursively calls BindToStorage on the rightmost component of the composite, */
    /* passing the rest of the composite as the pmkToLeft parameter for that call. */

    if (pmkToLeft!=NULL){

        IMoniker_Enum(iface,FALSE,&enumMoniker);
        IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
        IEnumMoniker_Release(enumMoniker);

        res=CreateAntiMoniker(&antiMk);
        res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
        IMoniker_Release(antiMk);

        res=CompositeMonikerImpl_BindToStorage(mostRigthMk,pbc,tempMk,riid,ppvResult);

        IMoniker_Release(tempMk);

        IMoniker_Release(mostRigthMk);

        return res;
    }
    else
        return IMoniker_BindToStorage(iface,pbc,NULL,riid,ppvResult);
}

/******************************************************************************
 *        CompositeMoniker_Reduce
 ******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar,
               IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
{
    HRESULT   res;
    IMoniker *tempMk,*antiMk,*mostRigthMk,*leftReducedComposedMk,*mostRigthReducedMk;
    IEnumMoniker *enumMoniker;

    TRACE("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);

    if (ppmkReduced==NULL)
        return E_POINTER;

    /* This method recursively calls Reduce for each of its component monikers. */

    if (ppmkToLeft==NULL){

        IMoniker_Enum(iface,FALSE,&enumMoniker);
        IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
        IEnumMoniker_Release(enumMoniker);

        res=CreateAntiMoniker(&antiMk);
        res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
        IMoniker_Release(antiMk);

        return CompositeMonikerImpl_Reduce(mostRigthMk,pbc,dwReduceHowFar,&tempMk, ppmkReduced);
    }
    else if (*ppmkToLeft==NULL)

        return IMoniker_Reduce(iface,pbc,dwReduceHowFar,NULL,ppmkReduced);

    else{

        /* separate the composite moniker in to left and right moniker */
        IMoniker_Enum(iface,FALSE,&enumMoniker);
        IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
        IEnumMoniker_Release(enumMoniker);

        res=CreateAntiMoniker(&antiMk);
        res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
        IMoniker_Release(antiMk);

        /* If any of the components  reduces itself, the method returns S_OK and passes back a composite */
        /* of the reduced components */
        if (IMoniker_Reduce(mostRigthMk,pbc,dwReduceHowFar,NULL,&mostRigthReducedMk) &&
            CompositeMonikerImpl_Reduce(mostRigthMk,pbc,dwReduceHowFar,&tempMk,&leftReducedComposedMk)
           )

            return CreateGenericComposite(leftReducedComposedMk,mostRigthReducedMk,ppmkReduced);

        else{
            /* If no reduction occurred, the method passes back the same moniker and returns MK_S_REDUCED_TO_SELF.*/

            IMoniker_AddRef(iface);

            *ppmkReduced=iface;

            return MK_S_REDUCED_TO_SELF;
        }
    }
}

/******************************************************************************
 *        CompositeMoniker_ComposeWith
 ******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_ComposeWith(IMoniker* iface, IMoniker* pmkRight,
               BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite)
{
    TRACE("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite);

    if ((ppmkComposite==NULL)||(pmkRight==NULL))
	return E_POINTER;

    *ppmkComposite=0;

    /* If fOnlyIfNotGeneric is TRUE, this method sets *pmkComposite to NULL and returns MK_E_NEEDGENERIC; */
    /* otherwise, the method returns the result of combining the two monikers by calling the */
    /* CreateGenericComposite function */

    if (fOnlyIfNotGeneric)
        return MK_E_NEEDGENERIC;

    return CreateGenericComposite(iface,pmkRight,ppmkComposite);
}

/******************************************************************************
 *        CompositeMoniker_Enum
 ******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
{
    CompositeMonikerImpl *This = (CompositeMonikerImpl *)iface;

    TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);

    if (ppenumMoniker == NULL)
        return E_POINTER;

    return EnumMonikerImpl_CreateEnumMoniker(This->tabMoniker,This->tabLastIndex,0,fForward,ppenumMoniker);
}

/******************************************************************************
 *        CompositeMoniker_IsEqual
 ******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
{
    IEnumMoniker *enumMoniker1,*enumMoniker2;
    IMoniker *tempMk1,*tempMk2;
    HRESULT res1,res2,res;

    TRACE("(%p,%p)\n",iface,pmkOtherMoniker);

    if (pmkOtherMoniker==NULL)
        return S_FALSE;

    /* This method returns S_OK if the components of both monikers are equal when compared in the */
    /* left-to-right order.*/
    IMoniker_Enum(pmkOtherMoniker,TRUE,&enumMoniker1);

    if (enumMoniker1==NULL)
        return S_FALSE;

    IMoniker_Enum(iface,TRUE,&enumMoniker2);

    while(1){

        res1=IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
        res2=IEnumMoniker_Next(enumMoniker2,1,&tempMk2,NULL);

        if((res1==S_OK)&&(res2==S_OK)){

            if(IMoniker_IsEqual(tempMk1,tempMk2)==S_FALSE){
                res= S_FALSE;
                break;
            }
            else
                continue;
        }
        else if ( (res1==S_FALSE) && (res2==S_FALSE) ){
                res = S_OK;
                break;
        }
        else{
            res = S_FALSE;
            break;
        }

        if (res1==S_OK)
            IMoniker_Release(tempMk1);

        if (res2==S_OK)
            IMoniker_Release(tempMk2);
    }

    IEnumMoniker_Release(enumMoniker1);
    IEnumMoniker_Release(enumMoniker2);

    return res;
}
/******************************************************************************
 *        CompositeMoniker_Hash
 ******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
{
    IEnumMoniker *enumMoniker;
    IMoniker *tempMk;
    HRESULT res;
    DWORD tempHash;

    TRACE("(%p,%p)\n",iface,pdwHash);

    if (pdwHash==NULL)
        return E_POINTER;

    res = IMoniker_Enum(iface,TRUE,&enumMoniker);
    if(FAILED(res))
        return res;

    while(1){
        res=IEnumMoniker_Next(enumMoniker,1,&tempMk,NULL);
        if(FAILED(res))
            break;
            
        res = IMoniker_Hash(tempMk, &tempHash);
        if(FAILED(res))
            break;
        *pdwHash = (*pdwHash * 37) + tempHash;
        
        IMoniker_Release(tempMk);
    }

    IEnumMoniker_Release(enumMoniker);

    return res;
}

/******************************************************************************
 *        CompositeMoniker_IsRunning
 ******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_IsRunning(IMoniker* iface, IBindCtx* pbc,
               IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning)
{
    IRunningObjectTable* rot;
    HRESULT res;
    IMoniker *tempMk,*antiMk,*mostRigthMk;
    IEnumMoniker *enumMoniker;

    TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);

    /* If pmkToLeft is non-NULL, this method composes pmkToLeft with this moniker and calls IsRunning on the result.*/
    if (pmkToLeft!=NULL){

        CreateGenericComposite(pmkToLeft,iface,&tempMk);

        res = IMoniker_IsRunning(tempMk,pbc,NULL,pmkNewlyRunning);

        IMoniker_Release(tempMk);

        return res;
    }
    else
        /* If pmkToLeft is NULL, this method returns S_OK if pmkNewlyRunning is non-NULL and is equal */
        /* to this moniker */

        if (pmkNewlyRunning!=NULL)

            if (IMoniker_IsEqual(iface,pmkNewlyRunning)==S_OK)
                return S_OK;

            else
                return S_FALSE;

        else{

            if (pbc==NULL)
                return E_POINTER;

            /* If pmkToLeft and pmkNewlyRunning are both NULL, this method checks the ROT to see whether */
            /* the moniker is running. If so, the method returns S_OK; otherwise, it recursively calls   */
            /* IMoniker::IsRunning on the rightmost component of the composite, passing the remainder of */
            /* the composite as the pmkToLeft parameter for that call.                                   */

             res=IBindCtx_GetRunningObjectTable(pbc,&rot);

            if (FAILED(res))
                return res;

            res = IRunningObjectTable_IsRunning(rot,iface);
            IRunningObjectTable_Release(rot);

            if(res==S_OK)
                return S_OK;

            else{

                IMoniker_Enum(iface,FALSE,&enumMoniker);
                IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
                IEnumMoniker_Release(enumMoniker);

                res=CreateAntiMoniker(&antiMk);
                res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
                IMoniker_Release(antiMk);

                res=IMoniker_IsRunning(mostRigthMk,pbc,tempMk,pmkNewlyRunning);

                IMoniker_Release(tempMk);
                IMoniker_Release(mostRigthMk);

                return res;
            }
        }
}

/******************************************************************************
 *        CompositeMoniker_GetTimeOfLastChange
 ******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc,
               IMoniker* pmkToLeft, FILETIME* pCompositeTime)
{
    IRunningObjectTable* rot;
    HRESULT res;
    IMoniker *tempMk,*antiMk,*mostRigthMk;
    IEnumMoniker *enumMoniker;

    TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pCompositeTime);

    if (pCompositeTime==NULL)
        return E_INVALIDARG;

    /* This method creates a composite of pmkToLeft (if non-NULL) and this moniker and uses the ROT to  */
    /* retrieve the time of last change. If the object is not in the ROT, the method recursively calls  */
    /* IMoniker::GetTimeOfLastChange on the rightmost component of the composite, passing the remainder */
    /* of the composite as the pmkToLeft parameter for that call.                                       */
    if (pmkToLeft!=NULL){

        res=CreateGenericComposite(pmkToLeft,iface,&tempMk);

        res=IBindCtx_GetRunningObjectTable(pbc,&rot);

        if (FAILED(res))
            return res;

        if (IRunningObjectTable_GetTimeOfLastChange(rot,tempMk,pCompositeTime)==S_OK)
            return res;
        else

            IMoniker_Enum(iface,FALSE,&enumMoniker);
            IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
            IEnumMoniker_Release(enumMoniker);

            res=CreateAntiMoniker(&antiMk);
            res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
            IMoniker_Release(antiMk);

            res=CompositeMonikerImpl_GetTimeOfLastChange(mostRigthMk,pbc,tempMk,pCompositeTime);

            IMoniker_Release(tempMk);
            IMoniker_Release(mostRigthMk);

            return res;
    }
    else
        return IMoniker_GetTimeOfLastChange(iface,pbc,NULL,pCompositeTime);
}

/******************************************************************************
 *        CompositeMoniker_Inverse
 ******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
{
    HRESULT res;
    IMoniker *tempMk,*antiMk,*mostRigthMk,*tempInvMk,*mostRigthInvMk;
    IEnumMoniker *enumMoniker;

    TRACE("(%p,%p)\n",iface,ppmk);

    if (ppmk==NULL)
        return E_POINTER;

    /* This method returns a composite moniker that consists of the inverses of each of the components */
    /* of the original composite, stored in reverse order */

    res=CreateAntiMoniker(&antiMk);
    res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
    IMoniker_Release(antiMk);

    if (tempMk==NULL)

        return IMoniker_Inverse(iface,ppmk);

    else{

        IMoniker_Enum(iface,FALSE,&enumMoniker);
        IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
        IEnumMoniker_Release(enumMoniker);

        IMoniker_Inverse(mostRigthMk,&mostRigthInvMk);
        CompositeMonikerImpl_Inverse(tempMk,&tempInvMk);

        res=CreateGenericComposite(mostRigthInvMk,tempInvMk,ppmk);

        IMoniker_Release(tempMk);
        IMoniker_Release(mostRigthMk);
        IMoniker_Release(tempInvMk);
        IMoniker_Release(mostRigthInvMk);

        return res;
    }
}

/******************************************************************************
 *        CompositeMoniker_CommonPrefixWith
 ******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_CommonPrefixWith(IMoniker* iface, IMoniker* pmkOther,
               IMoniker** ppmkPrefix)
{
    DWORD mkSys;
    HRESULT res1,res2;
    IMoniker *tempMk1,*tempMk2,*mostLeftMk1,*mostLeftMk2;
    IEnumMoniker *enumMoniker1,*enumMoniker2;
    ULONG i,nbCommonMk=0;

    /* If the other moniker is a composite, this method compares the components of each composite from left  */
    /* to right. The returned common prefix moniker might also be a composite moniker, depending on how many */
    /* of the leftmost components were common to both monikers.                                              */

    if (ppmkPrefix==NULL)
        return E_POINTER;

    *ppmkPrefix=0;

    if (pmkOther==NULL)
        return MK_E_NOPREFIX;

    IMoniker_IsSystemMoniker(pmkOther,&mkSys);

    if((mkSys==MKSYS_GENERICCOMPOSITE)){

        IMoniker_Enum(iface,TRUE,&enumMoniker1);
        IMoniker_Enum(pmkOther,TRUE,&enumMoniker2);

        while(1){

            res1=IEnumMoniker_Next(enumMoniker1,1,&mostLeftMk1,NULL);
            res2=IEnumMoniker_Next(enumMoniker2,1,&mostLeftMk2,NULL);

            if ((res1==S_FALSE) && (res2==S_FALSE)){

                /* If the monikers are equal, the method returns MK_S_US and sets ppmkPrefix to this moniker.*/
                *ppmkPrefix=iface;
                IMoniker_AddRef(iface);
                return  MK_S_US;
            }
            else if ((res1==S_OK) && (res2==S_OK)){

                if (IMoniker_IsEqual(mostLeftMk1,mostLeftMk2)==S_OK)

                    nbCommonMk++;

                else
                    break;

            }
            else if (res1==S_OK){

                /* If the other moniker is a prefix of this moniker, the method returns MK_S_HIM and sets */
                /* ppmkPrefix to the other moniker.                                                       */
                *ppmkPrefix=pmkOther;
                return MK_S_HIM;
            }
            else{
                /* If this moniker is a prefix of the other, this method returns MK_S_ME and sets ppmkPrefix */
                /* to this moniker.                                                                          */
                *ppmkPrefix=iface;
                return MK_S_ME;
            }
        }

        IEnumMoniker_Release(enumMoniker1);
        IEnumMoniker_Release(enumMoniker2);

        /* If there is no common prefix, this method returns MK_E_NOPREFIX and sets ppmkPrefix to NULL. */
        if (nbCommonMk==0)
            return MK_E_NOPREFIX;

        IEnumMoniker_Reset(enumMoniker1);

        IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);

        /* if we have more than one commun moniker the result will be a composite moniker */
        if (nbCommonMk>1){

            /* initialize the common prefix moniker with the composite of two first moniker (from the left)*/
            IEnumMoniker_Next(enumMoniker1,1,&tempMk2,NULL);
            CreateGenericComposite(tempMk1,tempMk2,ppmkPrefix);
            IMoniker_Release(tempMk1);
            IMoniker_Release(tempMk2);

            /* compose all common monikers in a composite moniker */
            for(i=0;i<nbCommonMk;i++){

                IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);

                CreateGenericComposite(*ppmkPrefix,tempMk1,&tempMk2);

                IMoniker_Release(*ppmkPrefix);

                IMoniker_Release(tempMk1);

                *ppmkPrefix=tempMk2;
            }
            return S_OK;
        }
        else{
            /* if we have only one commun moniker the result will be a simple moniker which is the most-left one*/
            *ppmkPrefix=tempMk1;

            return S_OK;
        }
    }
    else{
        /* If the other moniker is not a composite, the method simply compares it to the leftmost component
         of this moniker.*/

        IMoniker_Enum(iface,TRUE,&enumMoniker1);

        IEnumMoniker_Next(enumMoniker1,1,&mostLeftMk1,NULL);

        if (IMoniker_IsEqual(pmkOther,mostLeftMk1)==S_OK){

            *ppmkPrefix=pmkOther;

            return MK_S_HIM;
        }
        else
            return MK_E_NOPREFIX;
    }
}

/***************************************************************************************************
 *        GetAfterCommonPrefix (local function)
 *  This function returns a moniker that consist of the remainder when the common prefix is removed
 ***************************************************************************************************/
static VOID GetAfterCommonPrefix(IMoniker* pGenMk,IMoniker* commonMk,IMoniker** restMk)
{
    IMoniker *tempMk,*tempMk1,*tempMk2;
    IEnumMoniker *enumMoniker1,*enumMoniker2,*enumMoniker3;
    ULONG nbRestMk=0;
    DWORD mkSys;
    HRESULT res1,res2;

    *restMk=0;

    /* to create an enumerator for pGenMk with current position pointed on the first element after common  */
    /* prefix: enum the two monikers (left-right) then compare these enumerations (left-right) and stop  */
    /* on the first difference. */
    IMoniker_Enum(pGenMk,TRUE,&enumMoniker1);

    IMoniker_IsSystemMoniker(commonMk,&mkSys);

    if (mkSys==MKSYS_GENERICCOMPOSITE){

        IMoniker_Enum(commonMk,TRUE,&enumMoniker2);
        while(1){

            res1=IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
            res2=IEnumMoniker_Next(enumMoniker2,1,&tempMk2,NULL);

            if ((res1==S_FALSE)||(res2==S_FALSE)){

                if (res1==S_OK)

                    nbRestMk++;

                IMoniker_Release(tempMk1);
                IMoniker_Release(tempMk1);

                break;
            }
            IMoniker_Release(tempMk1);
            IMoniker_Release(tempMk1);
        }
    }
    else{
        IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);
        IMoniker_Release(tempMk1);
    }

    /* count the number of elements in the enumerator after the common prefix */
    IEnumMoniker_Clone(enumMoniker1,&enumMoniker3);

    for(;IEnumMoniker_Next(enumMoniker3,1,&tempMk,NULL)==S_OK;nbRestMk++)

        IMoniker_Release(tempMk);

    if (nbRestMk==0)
        return;

    /* create a generic composite moniker with monikers located after the common prefix */
    IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL);

    if (nbRestMk==1){

        *restMk= tempMk1;
        return;
    }
    else {

        IEnumMoniker_Next(enumMoniker1,1,&tempMk2,NULL);

        CreateGenericComposite(tempMk1,tempMk2,restMk);

        IMoniker_Release(tempMk1);

        IMoniker_Release(tempMk2);

        while(IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL)==S_OK){

            CreateGenericComposite(*restMk,tempMk1,&tempMk2);

            IMoniker_Release(tempMk1);

            IMoniker_Release(*restMk);

            *restMk=tempMk2;
        }
    }
}

/******************************************************************************
 *        CompositeMoniker_RelativePathTo
 ******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmkOther,
               IMoniker** ppmkRelPath)
{
    HRESULT res;
    IMoniker *restOtherMk=0,*restThisMk=0,*invRestThisMk=0,*commonMk=0;

    TRACE("(%p,%p,%p)\n",iface,pmkOther,ppmkRelPath);

    if (ppmkRelPath==NULL)
        return E_POINTER;

    *ppmkRelPath=0;

    /* This method finds the common prefix of the two monikers and creates two monikers that consist     */
    /* of the remainder when the common prefix is removed. Then it creates the inverse for the remainder */
    /* of this moniker and composes the remainder of the other moniker on the right of it.               */

    /* finds the common prefix of the two monikers */
    res=IMoniker_CommonPrefixWith(iface,pmkOther,&commonMk);

    /* if there's no common prefix or the two moniker are equal the relative is the other moniker */
    if ((res== MK_E_NOPREFIX)||(res==MK_S_US)){

        *ppmkRelPath=pmkOther;
        IMoniker_AddRef(pmkOther);
        return MK_S_HIM;
    }

    GetAfterCommonPrefix(iface,commonMk,&restThisMk);
    GetAfterCommonPrefix(pmkOther,commonMk,&restOtherMk);

    /* if other is a prefix of this moniker the relative path is the inverse of the remainder path of this */
    /* moniker when the common prefix is removed                                                           */
    if (res==MK_S_HIM){

        IMoniker_Inverse(restThisMk,ppmkRelPath);
        IMoniker_Release(restThisMk);
    }
    /* if this moniker is a prefix of other moniker the relative path is the remainder path of other moniker */
    /* when the common prefix is removed                                                                     */
    else if (res==MK_S_ME){

        *ppmkRelPath=restOtherMk;
        IMoniker_AddRef(restOtherMk);
    }
    /* the relative path is the inverse for the remainder of this moniker and the remainder of the other  */
    /* moniker on the right of it.                                                                        */
    else if (res==S_OK){

        IMoniker_Inverse(restThisMk,&invRestThisMk);
        IMoniker_Release(restThisMk);
        CreateGenericComposite(invRestThisMk,restOtherMk,ppmkRelPath);
        IMoniker_Release(invRestThisMk);
        IMoniker_Release(restOtherMk);
    }
    return S_OK;
}

/******************************************************************************
 *        CompositeMoniker_GetDisplayName
 ******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_GetDisplayName(IMoniker* iface, IBindCtx* pbc,
               IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName)
{
    ULONG lengthStr=1;
    IEnumMoniker *enumMoniker;
    IMoniker* tempMk;
    LPOLESTR tempStr;

    TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName);

    if (ppszDisplayName==NULL)
        return E_POINTER;

    *ppszDisplayName=CoTaskMemAlloc(sizeof(WCHAR));

    if (*ppszDisplayName==NULL)
        return E_OUTOFMEMORY;

    /* This method returns the concatenation of the display names returned by each component moniker of */
    /* the composite */

    **ppszDisplayName=0;

    IMoniker_Enum(iface,TRUE,&enumMoniker);

    while(IEnumMoniker_Next(enumMoniker,1,&tempMk,NULL)==S_OK){

        IMoniker_GetDisplayName(tempMk,pbc,NULL,&tempStr);

        lengthStr+=lstrlenW(tempStr);

        *ppszDisplayName=CoTaskMemRealloc(*ppszDisplayName,lengthStr * sizeof(WCHAR));

        if (*ppszDisplayName==NULL)
            return E_OUTOFMEMORY;

        strcatW(*ppszDisplayName,tempStr);

        CoTaskMemFree(tempStr);
        IMoniker_Release(tempMk);
    }

    IEnumMoniker_Release(enumMoniker);

    return S_OK;
}

/******************************************************************************
 *        CompositeMoniker_ParseDisplayName
 ******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_ParseDisplayName(IMoniker* iface, IBindCtx* pbc,
               IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten,
               IMoniker** ppmkOut)
{
    IEnumMoniker *enumMoniker;
    IMoniker *tempMk,*mostRigthMk,*antiMk;
    /* This method recursively calls IMoniker::ParseDisplayName on the rightmost component of the composite,*/
    /* passing everything else as the pmkToLeft parameter for that call. */

    /* get the most right moniker */
    IMoniker_Enum(iface,FALSE,&enumMoniker);
    IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
    IEnumMoniker_Release(enumMoniker);

    /* get the left moniker */
    CreateAntiMoniker(&antiMk);
    IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
    IMoniker_Release(antiMk);

    return IMoniker_ParseDisplayName(mostRigthMk,pbc,tempMk,pszDisplayName,pchEaten,ppmkOut);
}

/******************************************************************************
 *        CompositeMoniker_IsSystemMoniker
 ******************************************************************************/
static HRESULT WINAPI
CompositeMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
{
    TRACE("(%p,%p)\n",iface,pwdMksys);

    if (!pwdMksys)
        return E_POINTER;

    (*pwdMksys)=MKSYS_GENERICCOMPOSITE;

    return S_OK;
}

/*******************************************************************************
 *        CompositeMonikerIROTData_QueryInterface
 *******************************************************************************/
static HRESULT WINAPI
CompositeMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,
               VOID** ppvObject)
{

    IMoniker *This = impl_from_IROTData(iface);

    TRACE("(%p,%p,%p)\n",iface,riid,ppvObject);

    return CompositeMonikerImpl_QueryInterface(This, riid, ppvObject);
}

/***********************************************************************
 *        CompositeMonikerIROTData_AddRef
 */
static ULONG WINAPI
CompositeMonikerROTDataImpl_AddRef(IROTData *iface)
{
    IMoniker *This = impl_from_IROTData(iface);

    TRACE("(%p)\n",iface);

    return IMoniker_AddRef(This);
}

/***********************************************************************
 *        CompositeMonikerIROTData_Release
 */
static ULONG WINAPI CompositeMonikerROTDataImpl_Release(IROTData* iface)
{
    IMoniker *This = impl_from_IROTData(iface);

    TRACE("(%p)\n",iface);

    return IMoniker_Release(This);
}

/******************************************************************************
 *        CompositeMonikerIROTData_GetComparaisonData
 ******************************************************************************/
static HRESULT WINAPI
CompositeMonikerROTDataImpl_GetComparaisonData(IROTData* iface,
               BYTE* pbData, ULONG cbMax, ULONG* pcbData)
{
    FIXME("(),stub!\n");
    return E_NOTIMPL;
}

/******************************************************************************
 *        EnumMonikerImpl_QueryInterface
 ******************************************************************************/
static HRESULT WINAPI
EnumMonikerImpl_QueryInterface(IEnumMoniker* iface,REFIID riid,void** ppvObject)
{
    EnumMonikerImpl *This = (EnumMonikerImpl *)iface;

    TRACE("(%p,%p,%p)\n",This,riid,ppvObject);

    /* Perform a sanity check on the parameters.*/
    if ( (This==0) || (ppvObject==0) )
	return E_INVALIDARG;

    /* Initialize the return parameter */
    *ppvObject = 0;

    /* Compare the riid with the interface IDs implemented by this object.*/
    if (IsEqualIID(&IID_IUnknown, riid) || IsEqualIID(&IID_IEnumMoniker, riid))
        *ppvObject = iface;

    /* Check that we obtained an interface.*/
    if ((*ppvObject)==0)
        return E_NOINTERFACE;

    /* Query Interface always increases the reference count by one when it is successful */
    IEnumMoniker_AddRef(iface);

    return S_OK;
}

/******************************************************************************
 *        EnumMonikerImpl_AddRef
 ******************************************************************************/
static ULONG WINAPI
EnumMonikerImpl_AddRef(IEnumMoniker* iface)
{
    EnumMonikerImpl *This = (EnumMonikerImpl *)iface;

    TRACE("(%p)\n",This);

    return InterlockedIncrement(&This->ref);

}

/******************************************************************************
 *        EnumMonikerImpl_Release
 ******************************************************************************/
static ULONG WINAPI
EnumMonikerImpl_Release(IEnumMoniker* iface)
{
    EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
    ULONG i;
    ULONG ref;
    TRACE("(%p)\n",This);

    ref = InterlockedDecrement(&This->ref);

    /* destroy the object if there's no more reference on it */
    if (ref == 0) {

        for(i=0;i<This->tabSize;i++)
            IMoniker_Release(This->tabMoniker[i]);

        HeapFree(GetProcessHeap(),0,This->tabMoniker);
        HeapFree(GetProcessHeap(),0,This);
    }
    return ref;
}

/******************************************************************************
 *        EnumMonikerImpl_Next
 ******************************************************************************/
static HRESULT WINAPI
EnumMonikerImpl_Next(IEnumMoniker* iface,ULONG celt, IMoniker** rgelt,
               ULONG* pceltFethed)
{
    EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
    ULONG i;

    /* retrieve the requested number of moniker from the current position */
    for(i=0;((This->currentPos < This->tabSize) && (i < celt));i++)

        rgelt[i]=This->tabMoniker[This->currentPos++];

    if (pceltFethed!=NULL)
        *pceltFethed= i;

    if (i==celt)
        return S_OK;
    else
        return S_FALSE;
}

/******************************************************************************
 *        EnumMonikerImpl_Skip
 ******************************************************************************/
static HRESULT WINAPI
EnumMonikerImpl_Skip(IEnumMoniker* iface,ULONG celt)
{
    EnumMonikerImpl *This = (EnumMonikerImpl *)iface;

    if ((This->currentPos+celt) >= This->tabSize)
        return S_FALSE;

    This->currentPos+=celt;

    return S_OK;
}

/******************************************************************************
 *        EnumMonikerImpl_Reset
 ******************************************************************************/
static HRESULT WINAPI
EnumMonikerImpl_Reset(IEnumMoniker* iface)
{

    EnumMonikerImpl *This = (EnumMonikerImpl *)iface;

    This->currentPos=0;

    return S_OK;
}

/******************************************************************************
 *        EnumMonikerImpl_Clone
 ******************************************************************************/
static HRESULT WINAPI
EnumMonikerImpl_Clone(IEnumMoniker* iface,IEnumMoniker** ppenum)
{
    EnumMonikerImpl *This = (EnumMonikerImpl *)iface;

    return EnumMonikerImpl_CreateEnumMoniker(This->tabMoniker,This->tabSize,This->currentPos,TRUE,ppenum);
}

/********************************************************************************/
/* Virtual function table for the IROTData class                                */
static const IEnumMonikerVtbl VT_EnumMonikerImpl =
{
    EnumMonikerImpl_QueryInterface,
    EnumMonikerImpl_AddRef,
    EnumMonikerImpl_Release,
    EnumMonikerImpl_Next,
    EnumMonikerImpl_Skip,
    EnumMonikerImpl_Reset,
    EnumMonikerImpl_Clone
};

/******************************************************************************
 *        EnumMonikerImpl_CreateEnumMoniker
 ******************************************************************************/
static HRESULT
EnumMonikerImpl_CreateEnumMoniker(IMoniker** tabMoniker, ULONG tabSize,
               ULONG currentPos, BOOL leftToRigth, IEnumMoniker ** ppmk)
{
    EnumMonikerImpl* newEnumMoniker;
    int i;

    if (currentPos > tabSize)
        return E_INVALIDARG;

    newEnumMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(EnumMonikerImpl));

    if (newEnumMoniker == 0)
        return STG_E_INSUFFICIENTMEMORY;

    /* Initialize the virtual function table. */
    newEnumMoniker->lpVtbl       = &VT_EnumMonikerImpl;
    newEnumMoniker->ref          = 0;

    newEnumMoniker->tabSize=tabSize;
    newEnumMoniker->currentPos=currentPos;

    newEnumMoniker->tabMoniker=HeapAlloc(GetProcessHeap(),0,tabSize*sizeof(IMoniker));

    if (newEnumMoniker->tabMoniker==NULL) {
        HeapFree(GetProcessHeap(), 0, newEnumMoniker);
        return E_OUTOFMEMORY;
    }

    if (leftToRigth)
        for (i=0;i<tabSize;i++){

            newEnumMoniker->tabMoniker[i]=tabMoniker[i];
            IMoniker_AddRef(tabMoniker[i]);
        }
    else
        for (i=tabSize-1;i>=0;i--){

            newEnumMoniker->tabMoniker[tabSize-i-1]=tabMoniker[i];
            IMoniker_AddRef(tabMoniker[i]);
        }

    *ppmk=(IEnumMoniker*)newEnumMoniker;

    return S_OK;
}

/********************************************************************************/
/* Virtual function table for the CompositeMonikerImpl class which includes     */
/* IPersist, IPersistStream and IMoniker functions.                             */

static const IMonikerVtbl VT_CompositeMonikerImpl =
{
    CompositeMonikerImpl_QueryInterface,
    CompositeMonikerImpl_AddRef,
    CompositeMonikerImpl_Release,
    CompositeMonikerImpl_GetClassID,
    CompositeMonikerImpl_IsDirty,
    CompositeMonikerImpl_Load,
    CompositeMonikerImpl_Save,
    CompositeMonikerImpl_GetSizeMax,
    CompositeMonikerImpl_BindToObject,
    CompositeMonikerImpl_BindToStorage,
    CompositeMonikerImpl_Reduce,
    CompositeMonikerImpl_ComposeWith,
    CompositeMonikerImpl_Enum,
    CompositeMonikerImpl_IsEqual,
    CompositeMonikerImpl_Hash,
    CompositeMonikerImpl_IsRunning,
    CompositeMonikerImpl_GetTimeOfLastChange,
    CompositeMonikerImpl_Inverse,
    CompositeMonikerImpl_CommonPrefixWith,
    CompositeMonikerImpl_RelativePathTo,
    CompositeMonikerImpl_GetDisplayName,
    CompositeMonikerImpl_ParseDisplayName,
    CompositeMonikerImpl_IsSystemMoniker
};

/********************************************************************************/
/* Virtual function table for the IROTData class.                               */
static const IROTDataVtbl VT_ROTDataImpl =
{
    CompositeMonikerROTDataImpl_QueryInterface,
    CompositeMonikerROTDataImpl_AddRef,
    CompositeMonikerROTDataImpl_Release,
    CompositeMonikerROTDataImpl_GetComparaisonData
};

/******************************************************************************
 *         Composite-Moniker_Construct (local function)
 *******************************************************************************/
static HRESULT
CompositeMonikerImpl_Construct(CompositeMonikerImpl* This,
               LPMONIKER pmkFirst, LPMONIKER pmkRest)
{
    DWORD mkSys;
    IEnumMoniker *enumMoniker;
    IMoniker *tempMk;
    HRESULT res;

    TRACE("(%p,%p,%p)\n",This,pmkFirst,pmkRest);

    /* Initialize the virtual function table. */
    This->lpvtbl1      = &VT_CompositeMonikerImpl;
    This->lpvtbl2      = &VT_ROTDataImpl;
    This->ref          = 0;

    This->tabSize=BLOCK_TAB_SIZE;
    This->tabLastIndex=0;

    This->tabMoniker=HeapAlloc(GetProcessHeap(),0,This->tabSize*sizeof(IMoniker));
    if (This->tabMoniker==NULL)
        return E_OUTOFMEMORY;

    IMoniker_IsSystemMoniker(pmkFirst,&mkSys);

    /* put the first moniker contents in the beginning of the table */
    if (mkSys!=MKSYS_GENERICCOMPOSITE){

        This->tabMoniker[(This->tabLastIndex)++]=pmkFirst;
        IMoniker_AddRef(pmkFirst);
    }
    else{

        IMoniker_Enum(pmkFirst,TRUE,&enumMoniker);

        while(IEnumMoniker_Next(enumMoniker,1,&This->tabMoniker[This->tabLastIndex],NULL)==S_OK){


            if (++This->tabLastIndex==This->tabSize){

                This->tabSize+=BLOCK_TAB_SIZE;
                This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(IMoniker));

                if (This->tabMoniker==NULL)
                    return E_OUTOFMEMORY;
            }
        }

        IEnumMoniker_Release(enumMoniker);
    }

    /* put the rest moniker contents after the first one and make simplification if needed */

    IMoniker_IsSystemMoniker(pmkRest,&mkSys);

    if (mkSys!=MKSYS_GENERICCOMPOSITE){

        /* add a simple moniker to the moniker table */

        res=IMoniker_ComposeWith(This->tabMoniker[This->tabLastIndex-1],pmkRest,TRUE,&tempMk);

        if (res==MK_E_NEEDGENERIC){

            /* there's no simplification in this case */
            This->tabMoniker[This->tabLastIndex]=pmkRest;

            This->tabLastIndex++;

            IMoniker_AddRef(pmkRest);
        }
        else if (tempMk==NULL){

            /* we have an antimoniker after a simple moniker so we can make a simplification in this case */
            IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]);

            This->tabLastIndex--;
        }
        else if (SUCCEEDED(res)){

            /* the non-generic composition was successful so we can make a simplification in this case */
            IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]);

            This->tabMoniker[This->tabLastIndex-1]=tempMk;
        } else
            return res;

        /* resize tabMoniker if needed */
        if (This->tabLastIndex==This->tabSize){

            This->tabSize+=BLOCK_TAB_SIZE;

            This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(IMoniker));

            if (This->tabMoniker==NULL)
            return E_OUTOFMEMORY;
        }
    }
    else{

        /* add a composite moniker to the moniker table (do the same thing
         * for each moniker within the composite moniker as a simple moniker
         * (see above for how to add a simple moniker case) )
         */
        IMoniker_Enum(pmkRest,TRUE,&enumMoniker);

        while(IEnumMoniker_Next(enumMoniker,1,&This->tabMoniker[This->tabLastIndex],NULL)==S_OK){

            res=IMoniker_ComposeWith(This->tabMoniker[This->tabLastIndex-1],This->tabMoniker[This->tabLastIndex],TRUE,&tempMk);

            if (res==MK_E_NEEDGENERIC){

                This->tabLastIndex++;
            }
            else if (tempMk==NULL){

                IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]);
                IMoniker_Release(This->tabMoniker[This->tabLastIndex]);
                This->tabLastIndex--;
            }
            else{

                IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]);

                This->tabMoniker[This->tabLastIndex-1]=tempMk;
            }

            if (This->tabLastIndex==This->tabSize){

                This->tabSize+=BLOCK_TAB_SIZE;

                This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(IMoniker));

                if (This->tabMoniker==NULL)
                    return E_OUTOFMEMORY;
            }
        }

        IEnumMoniker_Release(enumMoniker);
    }

    return S_OK;
}

/******************************************************************************
 *        CreateGenericComposite	[OLE32.@]
 ******************************************************************************/
HRESULT WINAPI
CreateGenericComposite(LPMONIKER pmkFirst, LPMONIKER pmkRest,
               LPMONIKER* ppmkComposite)
{
    CompositeMonikerImpl* newCompositeMoniker = 0;
    HRESULT        hr = S_OK;

    TRACE("(%p,%p,%p)\n",pmkFirst,pmkRest,ppmkComposite);

    if (ppmkComposite==NULL)
        return E_POINTER;

    *ppmkComposite=0;

    if (pmkFirst==NULL && pmkRest!=NULL){

        *ppmkComposite=pmkRest;
        return S_OK;
    }
    else if (pmkFirst!=NULL && pmkRest==NULL){
        *ppmkComposite=pmkFirst;
        return S_OK;
    }
    else  if (pmkFirst==NULL && pmkRest==NULL)
        return S_OK;

    newCompositeMoniker = HeapAlloc(GetProcessHeap(), 0,sizeof(CompositeMonikerImpl));

    if (newCompositeMoniker == 0)
        return STG_E_INSUFFICIENTMEMORY;

    hr = CompositeMonikerImpl_Construct(newCompositeMoniker,pmkFirst,pmkRest);

    if (FAILED(hr)){

        HeapFree(GetProcessHeap(),0,newCompositeMoniker);
        return hr;
    }
    if (newCompositeMoniker->tabLastIndex==1)

        hr = IMoniker_QueryInterface(newCompositeMoniker->tabMoniker[0],&IID_IMoniker,(void**)ppmkComposite);
    else

        hr = IMoniker_QueryInterface((IMoniker*)newCompositeMoniker,&IID_IMoniker,(void**)ppmkComposite);

    return hr;
}

/******************************************************************************
 *        MonikerCommonPrefixWith	[OLE32.@]
 ******************************************************************************/
HRESULT WINAPI
MonikerCommonPrefixWith(IMoniker* pmkThis,IMoniker* pmkOther,IMoniker** ppmkCommon)
{
    FIXME("(),stub!\n");
    return E_NOTIMPL;
}
