void deepCloneAttachments(
          OSG::AttachmentContainer const      *src,
          OSG::AttachmentContainer            *dst,
    const std::vector<OSG::UInt16>            &shareGroupIds,
    const std::vector<OSG::UInt16>            &ignoreGroupIds)
{
    std::vector<const ReflexiveContainerType *> shareTypes;
    std::vector<const ReflexiveContainerType *> ignoreTypes;

    deepCloneAttachments(src, dst, shareTypes,    ignoreTypes,
                                   shareGroupIds, ignoreGroupIds);
}
void deepCloneAttachments(
          OSG::AttachmentContainer const *src,
          OSG::AttachmentContainer       *dst,
    const std::string                    &shareTypesString,
    const std::string                    &ignoreTypesString)
{
    std::vector<const ReflexiveContainerType *> shareTypes;
    std::vector<const ReflexiveContainerType *> ignoreTypes;
    std::vector<UInt16>                         shareGroupIds;
    std::vector<UInt16>                         ignoreGroupIds;

    appendTypesString(shareTypesString,  shareTypes);
    appendTypesString(ignoreTypesString, ignoreTypes);

    deepCloneAttachments(src, dst, shareTypes,    ignoreTypes,
                                   shareGroupIds, ignoreGroupIds);
}
NodeTransitPtr deepCloneTree(      
    const OSG::Node                                        *rootNode,
    const std::vector<const OSG::ReflexiveContainerType *> &shareTypes,
    const std::vector<const OSG::ReflexiveContainerType *> &ignoreTypes,
    const std::vector<OSG::UInt16>                         &shareGroupIds,
    const std::vector<OSG::UInt16>                         &ignoreGroupIds)
{
    NodeUnrecPtr rootClone(NULL);

    if(rootNode != NULL)
    {
        NodeUnrecPtr  childClone;
        NodeCore     *core       = rootNode->getCore();

        rootClone = Node::create();
        rootClone->setTravMask(rootNode->getTravMask());

        deepCloneAttachments(rootNode,      rootClone,
                             shareTypes,    ignoreTypes,
                             shareGroupIds, ignoreGroupIds);

        if(core != NULL)
        {
                  NodeCoreUnrecPtr    coreClone(NULL);
            const FieldContainerType &coreType   = core->getType();

            // test if core type should NOT be ignored
            if(!TypePredicates::typeInGroupIds (
                    ignoreGroupIds.begin(),
                    ignoreGroupIds.end(), coreType) &&
               !TypePredicates::typeDerivedFrom(
                    ignoreTypes.begin(),
                    ignoreTypes.end(),    coreType)   )
            {
                // test if core should be shared
                if(TypePredicates::typeInGroupIds (
                       shareGroupIds.begin(),
                       shareGroupIds.end(), coreType) ||
                   TypePredicates::typeDerivedFrom(
                       shareTypes.begin(),
                       shareTypes.end(),    coreType)   )
                {
                    // share core
                    coreClone = core;
                }
                else
                {
                    // clone core
                    coreClone = 
                        dynamic_pointer_cast<NodeCore>(
                            deepClone(core,
                                      shareTypes,    ignoreTypes,
                                      shareGroupIds, ignoreGroupIds));
                }
            }

            rootClone->setCore(coreClone);
        }

        for(UInt32 i = 0; i < rootNode->getNChildren(); ++i)
        {
            childClone = deepCloneTree(rootNode->getChild(i),
                                       shareTypes,    ignoreTypes,
                                       shareGroupIds, ignoreGroupIds);

            rootClone->addChild(childClone);
        }
    }

    return NodeTransitPtr(rootClone);
}