public void JsonLeaf(string propertyName, string value, bool isQuoted)
        {
            if (objectTypePending)
            {
                bool isTypeSpecifierLeaf = false;
                Type attributeTypeHint   = null;
                if (propertyName.Equals(TypeSpecifier))
                {
                    attributeTypeHint   = TypeAntiAliaser(value);
                    isTypeSpecifierLeaf = true;
                }
                else
                {
                    attributeTypeHint = inferCurrentTypeFromStack(false);
                }

                if (attributeTypeHint == null)
                {
                    string message            = String.Format("cant load type: \"{0}\" in json:{1}", value, json);
                    NoClueForTypeException ex = new NoClueForTypeException(message);
                    throw ex;
                }

                object      newObject    = newInstance(attributeTypeHint);
                ObjectFrame objectHolder = (ObjectFrame)objects.Peek();
                objectHolder.theObject = newObject;
                listener.onCreateObject(newObject);
                objectTypePending = false;
                if (isTypeSpecifierLeaf)
                {
                    return;
                }
            }

            if (objectTypePending || objects.Count == 0)
            {
                string message = string.Format("unable to set property {0} with value {1} because type is not found yet ", propertyName, value);
                throw new Exception(message);
            }

            string strError = null;

            if (TypeSpecifier != null && propertyName != null && propertyName.Equals(TypeSpecifier))
            {
                // todo raise a warning here or throw an exception in strict mode
            }
            else
            {
                objects.Peek().submitLeafToStack(propertyName, value, setValueinObject, listener);
            }

            if (strError != null)
            {
                throw new Exception(strError);
            }
        }
        Type inferCurrentTypeFromStack(bool autocreate)
        {
            if (this.objects.Count == 0)
            {
                return(null);
            }
            Type currentType = null;
            Type parentType  = null;

            for (int done = (this.objects.Count - 1); done >= 0; done--)
            {
                parentType  = currentType;
                currentType = null;
                ObjectFrame oFrame       = this.objects.ElementAt(done) as ObjectFrame;
                ArrayFrame  aFrame       = this.objects.ElementAt(done) as ArrayFrame;
                string      propertyName = null;
                if (oFrame != null)
                {
                    currentType = oFrame.theObject != null?oFrame.theObject.GetType() : null;

                    propertyName = oFrame.propertyName;
                }
                if (aFrame != null)
                {
                    propertyName = aFrame.propertyName;
                }

                if (currentType == null && parentType != null)
                {
                    //infer from the parentType and propertyName
                    if (propertyName != null)
                    {
                        PropertyInfo pi = parentType.GetProperty(propertyName);
                        if (pi != null)
                        {
                            currentType = pi.PropertyType;
                        }
                    }
                    else if (parentType.IsGenericType)
                    {
                        Type[] gtypes = parentType.GetGenericArguments();
                        if (gtypes != null && gtypes.Length == 1)
                        {
                            currentType = gtypes[0];
                        }
                    }
                }
                if (autocreate && currentType != null && oFrame != null && oFrame.theObject == null)
                {
                    oFrame.theObject = newInstance(currentType);
                }
            }
            return(currentType);
        }
        public void JsonEndObject(int pos)
        {
            if (objectTypePending)
            {
                if (objects.Count() > 0)
                {
                    ObjectFrame currentFrame = objects.Peek() as ObjectFrame;
                    if (currentFrame != null && currentFrame.theObject == null)
                    {
                        //fix parent chain
                        Type inferredType = inferCurrentTypeFromStack(true);
                        if (inferredType != null)
                        {
                            objectTypePending = false;
                        }
                    }
                }

                if (objectTypePending)
                {
                    string strMessage = String.Format("unable to determine type of object terminated at pos {0} in {1}", pos, json);
                    throw new NoClueForTypeException(strMessage);
                }
            }
            if (objects.Count < 1)
            {
                string strMessage = String.Format("too many object terminations at pos {0} in {1}", pos, json);
                throw new OverTerminatedObjectException(strMessage);
            }
            lastObject = objects.Pop();
            ObjectFrame lastFrame = lastObject as ObjectFrame;

            if (lastFrame == null)
            {
                throw new UnterminatedObjectException("unexpected non Object frame " + lastFrame.GetType().Name);
            }
            listener.onEndObject(lastFrame.theObject);
            if (objects.Count() > 0)
            {
                objects.Peek().submitObjectToStack(((ObjectFrame)lastObject).propertyName, ((ObjectFrame)lastObject).theObject, setValueinObject, listener);
            }
        }
        public void JsonStartObject(string propertyName, int pos)
        {
            // if the typeHint is not null create theobject
            // otherwise defer until a class attribute property is available
            //todo restruct typeHint usage based on whetherits thetop object
            ObjectFrame objectHolder = new ObjectFrame();

            objectHolder.propertyName = propertyName;
            objects.Push(objectHolder);
            if (typeHint != null)
            {
                object newObject = newInstance(typeHint);
                objectHolder.theObject = newObject;
                listener.onCreateObject(newObject);
                objectTypePending = false;
                typeHint          = null;
                return;
            }
            objectTypePending = true;
        }
        public void JsonStartObject(string propertyName, int pos)
        {
             // if the typeHint is not null create theobject 
            // otherwise defer until a class attribute property is available
            //todo restruct typeHint usage based on whetherits thetop object
            ObjectFrame objectHolder = new ObjectFrame();
            objectHolder.propertyName = propertyName;
            objects.Push(objectHolder);
            if (typeHint != null)
            {
                object newObject = newInstance(typeHint);
                objectHolder.theObject = newObject;
                listener.onCreateObject(newObject);
                objectTypePending = false;
                typeHint = null;
                return;
            }
            objectTypePending = true;

        }