public virtual long RegisterObject(object obj, out TokenObjectCategory type, bool root = false)
        {
            type = TokenObjectCategory.Unknown;
            var datum = Tuple.Create(obj);

            if (TryRegisterNullConstantForNullObject(obj, root, datum, out var registerObject))
            {
                return(registerObject);
            }

            var objectType = obj.GetType();

            RegisterType(objectType);
            // primatives are not subject to classification
            if (objectType.IsPrimitive || objectType == typeof(string))
            {
                _tokenType[objectType] = type = TokenObjectCategory.Value;
                // will get the current id, or all add a new entry and update the existing
                // ID counter
                if (!_constants.TryGetOrAdd(ref _idCounter, datum, out var cosntId))
                {
                    return(cosntId);
                }

                type |= TokenObjectCategory.NeedsUngraphing;
                _script.Constants.AddLast(
                    new IglDeclareValue(
                        cosntId,
                        _typeMap.GetId(objectType),
                        obj
                        ));
                if (root)
                {
                    _script.RootObjects.Add(cosntId);
                }
                return(cosntId);
            }

            // true if the object is added the first time
            if (_instances.TryGetOrAdd(ref _idCounter, datum, out var objectId))
            {
                type  = BackLogSerialization(obj);
                type |= TokenObjectCategory.NeedsUngraphing;
                _tokenType[objectType] = type;

                if (!HandleCustomPlacement(type, objectType, obj, objectId))
                {
                    _script.Declaration.AddLast(
                        new IglDeclareObject(
                            objectId,
                            _typeMap.GetId(objectType),
                            GetArrayInitDetails(obj)
                            ));
                }
                if (root)
                {
                    _script.RootObjects.Add(objectId);
                }
                return(objectId);
            }

            _tokenType.TryGetValue(objectType, out type);

            return(objectId);
        }
 HandleCustomPlacement(TokenObjectCategory type, Type objectType, object o, long objectId)
 {
     return(false);
 }
 public long RegisterRoot(object obj, out TokenObjectCategory type)
 {
     return(RegisterObject(obj, out type, true));
 }