STDMETHODIMP USBController::RemoveDeviceFilter(ULONG aPosition,
                                               IUSBDeviceFilter **aFilter)
{
#ifdef VBOX_WITH_USB

    CheckComArgOutPointerValid(aFilter);

    AutoCaller autoCaller(this);
    if (FAILED(autoCaller.rc())) return autoCaller.rc();

    /* the machine needs to be mutable */
    AutoMutableStateDependency adep(m->pParent);
    if (FAILED(adep.rc())) return adep.rc();

    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);

    if (!m->llDeviceFilters->size())
        return setError(E_INVALIDARG,
                        tr("The USB device filter list is empty"));

    if (aPosition >= m->llDeviceFilters->size())
        return setError(E_INVALIDARG,
                        tr("Invalid position: %lu (must be in range [0, %lu])"),
                        aPosition, m->llDeviceFilters->size() - 1);

    /* backup the list before modification */
    m->llDeviceFilters.backup();

    ComObjPtr<USBDeviceFilter> filter;
    {
        /* iterate to the position... */
        DeviceFilterList::iterator it = m->llDeviceFilters->begin();
        std::advance (it, aPosition);
        /* ...get an element from there... */
        filter = *it;
        /* ...and remove */
        filter->mInList = false;
        m->llDeviceFilters->erase (it);
    }

    /* cancel sharing (make an independent copy of data) */
    filter->unshare();

    filter.queryInterfaceTo(aFilter);

    /* notify the proxy (only when it makes sense) */
    if (filter->getData().mActive && Global::IsOnline(adep.machineState())
        && filter->getData().mRemote.isMatch (false))
    {
        USBProxyService *service = m->pHost->usbProxyService();
        ComAssertRet(service, E_FAIL);

        ComAssertRet(filter->getId() != NULL, E_FAIL);
        service->removeFilter(filter->getId());
        filter->getId() = NULL;
    }

    alock.release();
    AutoWriteLock mlock(m->pParent COMMA_LOCKVAL_SRC_POS);
    m->pParent->setModified(Machine::IsModified_USB);
    mlock.release();

    return S_OK;

#else /* VBOX_WITH_USB */

    NOREF(aPosition);
    NOREF(aFilter);
    ReturnComNotImplemented();

#endif /* VBOX_WITH_USB */
}
STDMETHODIMP USBController::InsertDeviceFilter(ULONG aPosition,
                                               IUSBDeviceFilter *aFilter)
{
#ifdef VBOX_WITH_USB

    CheckComArgNotNull(aFilter);

    AutoCaller autoCaller(this);
    if (FAILED(autoCaller.rc())) return autoCaller.rc();

    /* the machine needs to be mutable */
    AutoMutableStateDependency adep(m->pParent);
    if (FAILED(adep.rc())) return adep.rc();

    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);

    ComObjPtr<USBDeviceFilter> filter = static_cast<USBDeviceFilter*>(aFilter);
    // @todo r=dj make sure the input object is actually from us
//     if (!filter)
//         return setError (E_INVALIDARG,
//             tr ("The given USB device filter is not created within "
//                 "this VirtualBox instance"));

    if (filter->mInList)
        return setError(VBOX_E_INVALID_OBJECT_STATE,
                        tr("The given USB device filter is already in the list"));

    /* backup the list before modification */
    m->llDeviceFilters.backup();

    /* iterate to the position... */
    DeviceFilterList::iterator it;
    if (aPosition < m->llDeviceFilters->size())
    {
        it = m->llDeviceFilters->begin();
        std::advance (it, aPosition);
    }
    else
        it = m->llDeviceFilters->end();
    /* ...and insert */
    m->llDeviceFilters->insert (it, filter);
    filter->mInList = true;

    /* notify the proxy (only when it makes sense) */
    if (filter->getData().mActive && Global::IsOnline(adep.machineState())
        && filter->getData().mRemote.isMatch (false))
    {
        USBProxyService *service = m->pHost->usbProxyService();
        ComAssertRet(service, E_FAIL);

        ComAssertRet(filter->getId() == NULL, E_FAIL);
        filter->getId() = service->insertFilter (&filter->getData().mUSBFilter);
    }

    alock.release();
    AutoWriteLock mlock(m->pParent COMMA_LOCKVAL_SRC_POS);
    m->pParent->setModified(Machine::IsModified_USB);
    mlock.release();

    return S_OK;

#else /* VBOX_WITH_USB */

    NOREF(aPosition);
    NOREF(aFilter);
    ReturnComNotImplemented();

#endif /* VBOX_WITH_USB */
}