void OnIncomingSceneObject(SceneObjectGroup so)
        {
            if (!so.IsAttachment)
                return;

            if (so.AttachedAvatar == UUID.Zero || Scene.UserManagementModule.IsLocalGridUser(so.AttachedAvatar))
                return;

            // foreign user
            AgentCircuitData aCircuit = Scene.AuthenticateHandler.GetAgentCircuitData(so.AttachedAvatar);
            if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
            {
                if (aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
                {
                    string url = aCircuit.ServiceURLs["AssetServerURI"].ToString();
                    m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Incoming attachment {0} for HG user {1} with asset server {2}", so.Name, so.AttachedAvatar, url);
                    Dictionary<UUID, sbyte> ids = new Dictionary<UUID, sbyte>();
                    HGUuidGatherer uuidGatherer = new HGUuidGatherer(Scene.AssetService, url);
                    uuidGatherer.GatherAssetUuids(so, ids);

                    foreach (KeyValuePair<UUID, sbyte> kvp in ids)
                        uuidGatherer.FetchAsset(kvp.Key);
                }
            }
        }
        public override bool HandleIncomingSceneObject(SceneObjectGroup so, Vector3 newPosition)
        {
            // FIXME: We must make it so that we can use SOG.IsAttachment here.  At the moment it is always null!
            if (!so.IsAttachmentCheckFull())
                return base.HandleIncomingSceneObject(so, newPosition);

            // Equally, we can't use so.AttachedAvatar here.
            if (so.OwnerID == UUID.Zero || Scene.UserManagementModule.IsLocalGridUser(so.OwnerID))
                return base.HandleIncomingSceneObject(so, newPosition);

            // foreign user
            AgentCircuitData aCircuit = Scene.AuthenticateHandler.GetAgentCircuitData(so.OwnerID);
            if (aCircuit != null)
            {
                if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) == 0)
                {
                    // We have already pulled the necessary attachments from the source grid.
                    base.HandleIncomingSceneObject(so, newPosition);
                }
                else
                {
                    if (aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
                    {
                        m_incomingSceneObjectEngine.QueueJob(
                            string.Format("HG UUID Gather for attachment {0} for {1}", so.Name, aCircuit.Name), 
                            () => 
                            {
                                string url = aCircuit.ServiceURLs["AssetServerURI"].ToString();
    //                            m_log.DebugFormat(
    //                                "[HG ENTITY TRANSFER MODULE]: Incoming attachment {0} for HG user {1} with asset service {2}", 
    //                                so.Name, so.AttachedAvatar, url);

                                IDictionary<UUID, sbyte> ids = new Dictionary<UUID, sbyte>();
                                HGUuidGatherer uuidGatherer 
                                    = new HGUuidGatherer(Scene.AssetService, url, ids);
                                uuidGatherer.AddForInspection(so);

                                while (!uuidGatherer.Complete)
                                {
                                    int tickStart = Util.EnvironmentTickCount();

                                    UUID? nextUuid = uuidGatherer.NextUuidToInspect;
                                    uuidGatherer.GatherNext();

    //                                m_log.DebugFormat(
    //                                    "[HG ENTITY TRANSFER]: Gathered attachment asset uuid {0} for object {1} for HG user {2} took {3} ms with asset service {4}",
    //                                    nextUuid, so.Name, so.OwnerID, Util.EnvironmentTickCountSubtract(tickStart), url);

                                    int ticksElapsed = Util.EnvironmentTickCountSubtract(tickStart);

                                    if (ticksElapsed > 30000)
                                    {
                                        m_log.WarnFormat(
                                            "[HG ENTITY TRANSFER]: Removing incoming scene object jobs for HG user {0} as gather of {1} from {2} took {3} ms to respond (> {4} ms)",
                                            so.OwnerID, so.Name, url, ticksElapsed, 30000);

                                        RemoveIncomingSceneObjectJobs(so.OwnerID.ToString());

                                        return;
                                    }                                                           
                                }

    //                            m_log.DebugFormat(
    //                                "[HG ENTITY TRANSFER]: Fetching {0} assets for attachment {1} for HG user {2} with asset service {3}",
    //                                ids.Count, so.Name, so.OwnerID, url);

                                foreach (KeyValuePair<UUID, sbyte> kvp in ids)
                                {
                                    int tickStart = Util.EnvironmentTickCount();

                                    uuidGatherer.FetchAsset(kvp.Key);   

                                    int ticksElapsed = Util.EnvironmentTickCountSubtract(tickStart);

                                    if (ticksElapsed > 30000)
                                    {
                                        m_log.WarnFormat(
                                            "[HG ENTITY TRANSFER]: Removing incoming scene object jobs for HG user {0} as fetch of {1} from {2} took {3} ms to respond (> {4} ms)",
                                            so.OwnerID, kvp.Key, url, ticksElapsed, 30000);

                                        RemoveIncomingSceneObjectJobs(so.OwnerID.ToString());

                                        return;
                                    }   
                                }

                                base.HandleIncomingSceneObject(so, newPosition);

    //                            m_log.DebugFormat(
    //                                "[HG ENTITY TRANSFER MODULE]: Completed incoming attachment {0} for HG user {1} with asset server {2}", 
    //                                so.Name, so.OwnerID, url);
                            },                             
                            so.OwnerID.ToString());
                    }
                }
            }

            return true;
        }