virtual void Visit(const DeviceCreateDesc& createDesc)
        {
            DeviceCreateDesc* devDesc;
            
            // If found, mark as enumerated and we are done.
            DeviceCreateDesc* descCandidate = 0;

            for(devDesc = pManager->Devices.GetFirst();
                !pManager->Devices.IsNull(devDesc);  devDesc = devDesc->pNext)
            {
                DeviceCreateDesc::MatchResult mr = devDesc->MatchDevice(createDesc, &descCandidate);
                if (mr == DeviceCreateDesc::Match_Found)
                {
                    devDesc->Enumerated = true;
                    return;
                }
            }

            // Update candidate (this may involve writing fields to HMDDevice createDesc).
            if (descCandidate && descCandidate->UpdateMatchedCandidate(createDesc))
            {
                descCandidate->Enumerated = true;
                return;
            }

            // If not found, add new device.
            //  - This stores a new descriptor with
            //    {pDevice = 0, HandleCount = 1, Enumerated = true}
            DeviceCreateDesc* desc = createDesc.Clone();
            desc->pLock = pManager->pCreateDesc->pLock;
            pManager->Devices.PushBack(desc);

            pManager->CallOnDeviceAdded(desc);
        }
Ptr<DeviceCreateDesc> DeviceManagerImpl::FindDevice(
    const String& path, 
    DeviceType deviceType)
{
    Lock::Locker deviceLock(GetLock());
    DeviceCreateDesc* devDesc;

    for (devDesc = Devices.GetFirst();
        !Devices.IsNull(devDesc);  devDesc = devDesc->pNext)
    {
        if ((deviceType == Device_None || deviceType == devDesc->Type) &&
            devDesc->MatchDevice(path))
            return devDesc;
    }
    return NULL;
}
Ptr<DeviceCreateDesc> DeviceManagerImpl::AddDevice_NeedsLock(
    const DeviceCreateDesc& createDesc)
{
    // If found, mark as enumerated and we are done.
    DeviceCreateDesc* descCandidate = 0;

    for(DeviceCreateDesc* devDesc = Devices.GetFirst();
        !Devices.IsNull(devDesc);  devDesc = devDesc->pNext)
    {
        DeviceCreateDesc::MatchResult mr = devDesc->MatchDevice(createDesc, &descCandidate);
        if (mr == DeviceCreateDesc::Match_Found)
        {
            devDesc->Enumerated = true;
            if (!devDesc->pDevice)
                CallOnDeviceAdded(devDesc);
            return devDesc;
        }
    }

    // Update candidate (this may involve writing fields to HMDDevice createDesc).
    if (descCandidate)
    {
        bool newDevice = false;
        if (descCandidate->UpdateMatchedCandidate(createDesc, &newDevice))
        {
            descCandidate->Enumerated = true;
            if (!descCandidate->pDevice || newDevice)
                CallOnDeviceAdded(descCandidate);
            return descCandidate;
        }
    }

    // If not found, add new device.
    //  - This stores a new descriptor with
    //    {pDevice = 0, HandleCount = 1, Enumerated = true}
    DeviceCreateDesc* desc = createDesc.Clone();
    desc->pLock = pCreateDesc->pLock;
    Devices.PushBack(desc);
    desc->Enumerated = true;

    CallOnDeviceAdded(desc);

    return desc;
}