QPDF::copyForeignObject(QPDFObjectHandle foreign)
{
    // Do not preclude use of copyForeignObject on page objects. It is
    // a documented use case to copy pages this way if the intention
    // is to not update the pages tree.
    if (! foreign.isIndirect())
    {
        QTC::TC("qpdf", "QPDF copyForeign direct");
	throw std::logic_error(
	    "QPDF::copyForeign called with direct object handle");
    }
    QPDF* other = foreign.getOwningQPDF();
    if (other == this)
    {
        QTC::TC("qpdf", "QPDF copyForeign not foreign");
        throw std::logic_error(
            "QPDF::copyForeign called with object from this QPDF");
    }

    ObjCopier& obj_copier = this->m->object_copiers[other->m->unique_id];
    if (! obj_copier.visiting.empty())
    {
        throw std::logic_error("obj_copier.visiting is not empty"
                               " at the beginning of copyForeignObject");
    }

    // Make sure we have an object in this file for every referenced
    // object in the old file.  obj_copier.object_map maps foreign
    // QPDFObjGen to local objects.  For everything new that we have
    // to copy, the local object will be a reservation, unless it is a
    // stream, in which case the local object will already be a
    // stream.
    reserveObjects(foreign, obj_copier, true);

    if (! obj_copier.visiting.empty())
    {
        throw std::logic_error("obj_copier.visiting is not empty"
                               " after reserving objects");
    }

    // Copy any new objects and replace the reservations.
    for (std::vector<QPDFObjectHandle>::iterator iter =
             obj_copier.to_copy.begin();
         iter != obj_copier.to_copy.end(); ++iter)
    {
        QPDFObjectHandle& to_copy = *iter;
        QPDFObjectHandle copy =
            replaceForeignIndirectObjects(to_copy, obj_copier, true);
        if (! to_copy.isStream())
        {
            QPDFObjGen og(to_copy.getObjGen());
            replaceReserved(obj_copier.object_map[og], copy);
        }
    }
    obj_copier.to_copy.clear();

    return obj_copier.object_map[foreign.getObjGen()];
}
QPDF::copyForeignObject(QPDFObjectHandle foreign)
{
     
     
     
    if (! foreign.isIndirect())
    {
        QTC::TC("qpdf", "QPDF copyForeign direct");
	throw std::logic_error(
	    "QPDF::copyForeign called with direct object handle");
    }
    QPDF* other = foreign.getOwningQPDF();
    if (other == this)
    {
        QTC::TC("qpdf", "QPDF copyForeign not foreign");
        throw std::logic_error(
            "QPDF::copyForeign called with object from this QPDF");
    }

    ObjCopier& obj_copier = this->m->object_copiers[other->m->unique_id];
    if (! obj_copier.visiting.empty())
    {
        throw std::logic_error("obj_copier.visiting is not empty"
                               " at the beginning of copyForeignObject");
    }

     
     
     
     
     
     
    reserveObjects(foreign, obj_copier, true);

    if (! obj_copier.visiting.empty())
    {
        throw std::logic_error("obj_copier.visiting is not empty"
                               " after reserving objects");
    }

     
    for (std::vector<QPDFObjectHandle>::iterator iter =
             obj_copier.to_copy.begin();
         iter != obj_copier.to_copy.end(); ++iter)
    {
        QPDFObjectHandle& to_copy = *iter;
        QPDFObjectHandle copy =
            replaceForeignIndirectObjects(to_copy, obj_copier, true);
        if (! to_copy.isStream())
        {
            QPDFObjGen og(to_copy.getObjGen());
            replaceReserved(obj_copier.object_map[og], copy);
        }
    }
    obj_copier.to_copy.clear();

    return obj_copier.object_map[foreign.getObjGen()];
}