/**
 * Return two lists, a list of addresses that would be removed from
 * mLinkAddresses and a list of addresses that would be added to
 * mLinkAddress which would then result in target and mLinkAddresses
 * being the same list.
 *
 * @param target is a LinkProperties with the new list of addresses
 * @return the removed and added lists.
 */
ECode CLinkProperties::CompareAddresses(
    /* [in] */ ILinkProperties* target,
    /* [out] */ ICompareResult** result)
{
    VALIDATE_NOT_NULL(result);

    /*
     * Duplicate the LinkAddresses into removed, we will be removing
     * address which are common between mLinkAddresses and target
     * leaving the addresses that are different. And address which
     * are in target but not in mLinkAddresses are placed in the
     * addedAddresses.
     */

    List< AutoPtr<ILinkAddress> > cprRemoved(mLinkAddresses);
    List< AutoPtr<ILinkAddress> >::Iterator iter;
    AutoPtr<ICompareResult> cprResult;
    CCompareResult::New((ICompareResult**)&cprResult);

    if (target != NULL) {
        AutoPtr<IObjectContainer> container;
        FAIL_RETURN(target->GetLinkAddresses((IObjectContainer **)&container));
        AutoPtr<IObjectEnumerator> emu;
        FAIL_RETURN(container->GetObjectEnumerator((IObjectEnumerator **)&emu))

        Boolean hasNext;
        while (emu->MoveNext(&hasNext), hasNext) {
            AutoPtr<ILinkAddress> newAddress;
            emu->Current((IInterface**)&newAddress);

            iter = Find(cprRemoved.Begin(), cprRemoved.End(), newAddress);
            if (iter == cprRemoved.End()) {
                cprResult->AddAdded(newAddress);
            }
            else {
                cprRemoved.Erase(iter);
            }
        }
    }

    for (iter = cprRemoved.Begin(); iter != cprRemoved.End(); ++iter) {
        cprResult->AddRemoved(*iter);
    }

    *result = cprResult;
    REFCOUNT_ADD(*result);
    return NOERROR;
}
/**
 * Return two lists, a list of routes that would be removed from
 * mRoutes and a list of routes that would be added to
 * mRoutes which would then result in target and mRoutes
 * being the same list.
 *
 * @param target is a LinkProperties with the new list of routes
 * @return the removed and added lists.
 */
ECode CLinkProperties::CompareRoutes(
    /* [in] */ ILinkProperties* target,
    /* [out] */ ICompareResult** result)
{
    VALIDATE_NOT_NULL(result);

    List< AutoPtr<IRouteInfo> > cprRemoved(mRoutes);
    List< AutoPtr<IRouteInfo> >::Iterator iter;
    AutoPtr<ICompareResult> cprResult;
    CCompareResult::New((ICompareResult**)&cprResult);

    if (target != NULL) {
        AutoPtr<IObjectContainer> container;
        FAIL_RETURN(target->GetRoutes((IObjectContainer **)&container));
        AutoPtr<IObjectEnumerator> emu;
        FAIL_RETURN(container->GetObjectEnumerator((IObjectEnumerator **)&emu))
        Boolean hasNext;
        while(emu->MoveNext(&hasNext), hasNext) {
            AutoPtr<IRouteInfo> newRoute;
            emu->Current((IInterface**)&newRoute);

            iter = Find(cprRemoved.Begin(), cprRemoved.End(), newRoute);
            if (iter == cprRemoved.End()) {
                cprResult->AddAdded(newRoute);
            }
            else {
                cprRemoved.Erase(iter);
            }
        }
    }

    for (iter = cprRemoved.Begin(); iter != cprRemoved.End(); ++iter) {
        cprResult->AddRemoved(*iter);
    }
    *result = cprResult;
    REFCOUNT_ADD(*result);
    return NOERROR;
}