//public PlTerm Origin;

        public DelegateObjectInProlog(DelegateObjectInPrologKey key)
        {
            Key = key;
            Type eht = key.DelegateType;

            SetInstanceOfDelegateType(eht);
            SyncLock = Delegate;
        }
        static public Delegate cliNewDelegateTerm(Type fi, PlTerm prologPred, bool saveKey)
        {
            if (prologPred.IsCompound)
            {
                if (prologPred.Name == "delegate")
                {
                    if (prologPred.Arity == 1)
                    {
                        return(cliNewDelegateTerm(fi, prologPred.Arg(0), saveKey));
                    }
                    Type dt  = GetTypeThrowIfMissing(prologPred.Arg(0));
                    var  obj = cliNewDelegateTerm(dt, prologPred.Arg(1), saveKey);
                    return((Delegate)RecastObject(fi, obj, dt));
                }
                if (prologPred.Name == "@")
                {
                    return((Delegate)RecastObject(fi, tag_to_object((string)prologPred.Arg(0)), null));
                }
            }
            string pn = prologPred.Name;

            if (pn == "." || pn == "{}")
            {
                // Warn("Delegate term = " + pn);
            }
            var Key = new DelegateObjectInPrologKey
            {
                Name         = PredicateName(prologPred),
                Arity        = PredicateArity(prologPred),
                Module       = PredicateModule(prologPred),
                DelegateType = fi
            };
            //uint fid = libpl.PL_open_foreign_frame();
            //Key.Origin = prologPred.Copy();

            DelegateObjectInProlog handlerInProlog;

            lock (PrologDelegateHandlers)
            {
                if (PrologDelegateHandlers.TryGetValue(Key, out handlerInProlog))
                {
                    //   fi.RemoveEventHandler(getInstance, handlerInProlog.Delegate);
                    PrologDelegateHandlers.Remove(Key);
                }
                handlerInProlog = new DelegateObjectInProlog(Key);
                if (saveKey)
                {
                    PrologDelegateHandlers.Add(Key, handlerInProlog);
                }
                // fi.AddEventHandler(getInstance, handlerInProlog.Delegate);
            }
            return(handlerInProlog.Delegate);
        }
        static public Delegate cliNewDelegateTerm(Type fi, PlTerm prologPred, bool saveKey)
        {
            if (prologPred.IsCompound)
            {
                if (prologPred.Name == "delegate")
                {
                    if (prologPred.Arity == 1)
                    {
                        return cliNewDelegateTerm(fi, prologPred.Arg(0), saveKey);
                    }
                    Type dt = GetTypeThrowIfMissing(prologPred.Arg(0));
                    var obj = cliNewDelegateTerm(dt, prologPred.Arg(1), saveKey);
                    return (Delegate)RecastObject(fi, obj, dt);
                }
                if (prologPred.Name == "@")
                {
                    return (Delegate)RecastObject(fi, tag_to_object((string)prologPred.Arg(0)), null);
                }
            }
            string pn = prologPred.Name;
            if (pn == "." || pn == "{}")
            {
                // Warn("Delegate term = " + pn);
            }
            var Key = new DelegateObjectInPrologKey
            {
                Name = PredicateName(prologPred),
                Arity = PredicateArity(prologPred),
                Module = PredicateModule(prologPred),
                DelegateType = fi
            };
            //uint fid = libpl.PL_open_foreign_frame();
            //Key.Origin = prologPred.Copy();

            DelegateObjectInProlog handlerInProlog;
            lock (PrologDelegateHandlers)
            {
                if (PrologDelegateHandlers.TryGetValue(Key, out handlerInProlog))
                {
                    //   fi.RemoveEventHandler(getInstance, handlerInProlog.Delegate);
                    PrologDelegateHandlers.Remove(Key);
                }
                handlerInProlog = new DelegateObjectInProlog(Key);
                if (saveKey) PrologDelegateHandlers.Add(Key, handlerInProlog);
                // fi.AddEventHandler(getInstance, handlerInProlog.Delegate);
            }
            return handlerInProlog.Delegate;

        }
        //public PlTerm Origin;

        public DelegateObjectInProlog(DelegateObjectInPrologKey key)
        {
            Key = key;
            Type eht = key.DelegateType;
            SetInstanceOfDelegateType(eht);
            SyncLock = Delegate;
        }