src/main/java/com/cedarsoftware/util/io/ObjectResolver.java
protected Object readIfMatching(final Object o, final Class compType, final Deque<JsonObject<String, Object>> stack)
    {
        if (o == null)
        {
            throw new JsonIoException("Bug in json-io, null must be checked before calling this method.");
        }

        if (compType != null && notCustom(compType))
        {
            return null;
        }

        final boolean isJsonObject = o instanceof JsonObject;
        if (!isJsonObject && compType == null)
        {   // If not a JsonObject (like a Long that represents a date, then compType must be set)
            return null;
        }

        Class c;
        boolean needsType = false;

        // Set up class type to check against reader classes (specified as @type, or jObj.target, or compType)
        if (isJsonObject)
        {
            JsonObject jObj = (JsonObject) o;
            if (jObj.isReference())
            {
                return null;
            }

            if (jObj.target == null)
            {   // '@type' parameter used (not target instance)
                String typeStr = null;
                try
                {
                    Object type =  jObj.type;
                    if (type != null)
                    {
                        typeStr = (String) type;
                        c = MetaUtils.classForName((String) type, classLoader);
                    }
                    else
                    {
                        if (compType != null)
                        {
                            c = compType;
                            needsType = true;
                        }
                        else
                        {
                            return null;
                        }
                    }
                    createJavaObjectInstance(c, jObj);
                }
                catch(Exception e)
                {
                    throw new JsonIoException("Class listed in @type [" + typeStr + "] is not found", e);
                }
            }
            else
            {   // Type inferred from target object
                c = jObj.target.getClass();
            }
        }
        else
        {
            c = compType;
        }

        if (notCustom(c))
        {
            return null;
        }

        JsonReader.JsonClassReaderBase closestReader = getCustomReader(c);

        if (closestReader == null)
        {
            return null;
        }

        if (needsType)
        {
            ((JsonObject)o).setType(c.getName());
        }

        Object read;
        if (closestReader instanceof JsonReader.JsonClassReaderEx)
        {
            read = ((JsonReader.JsonClassReaderEx)closestReader).read(o, stack, getReader().getArgs());
        }
        else
        {
            read = ((JsonReader.JsonClassReader)closestReader).read(o, stack);
        }
		return read;
    }
protected Object readIfMatching(final Object o, final Class compType, final Deque<JsonObject<String, Object>> stack)
    {
        if (o == null)
        {
            throw new JsonIoException("Bug in json-io, null must be checked before calling this method.");
        }

        if (compType != null && notCustom(compType))
        {
            return null;
        }

        final boolean isJsonObject = o instanceof JsonObject;
        if (!isJsonObject && compType == null)
        {   // If not a JsonObject (like a Long that represents a date, then compType must be set)
            return null;
        }

        Class c;
        boolean needsType = false;

        // Set up class type to check against reader classes (specified as @type, or jObj.target, or compType)
        if (isJsonObject)
        {
            JsonObject jObj = (JsonObject) o;
            if (jObj.isReference())
            {
                return null;
            }

            if (jObj.target == null)
            {   // '@type' parameter used (not target instance)
                String typeStr = null;
                try
                {
                    Object type =  jObj.type;
                    if (type != null)
                    {
                        typeStr = (String) type;
                        c = MetaUtils.classForName((String) type, classLoader);
                    }
                    else
                    {
                        if (compType != null)
                        {
                            c = compType;
                            needsType = true;
                        }
                        else
                        {
                            return null;
                        }
                    }
                    createJavaObjectInstance(c, jObj);
                }
                catch(Exception e)
                {
                    throw new JsonIoException("Class listed in @type [" + typeStr + "] is not found", e);
                }
            }
            else
            {   // Type inferred from target object
                c = jObj.target.getClass();
            }
        }
        else
        {
            c = compType;
        }

        if (notCustom(c))
        {
            return null;
        }

        JsonReader.JsonClassReaderBase closestReader = getCustomReader(c);

        if (closestReader == null)
        {
            return null;
        }

        if (needsType)
        {
            ((JsonObject)o).setType(c.getName());
        }

        Object read;
        if (closestReader instanceof JsonReader.JsonClassReaderEx)
        {
            read = ((JsonReader.JsonClassReaderEx)closestReader).read(o, stack, getReader().getArgs());
        }
        else
        {
            read = ((JsonReader.JsonClassReader)closestReader).read(o, stack);
        }
		return read;
    }
Convert the passed in object (o) to a proper Java object.  If the passed in object (o) has a custom reader
associated to it, then have it convert the object.  If there is no custom reader, then return null.
@param o Object to read (convert).  Will be either a JsonObject or a JSON primitive String, long, boolean,
double, or null.
@param compType Class destination type to which the passed in object should be converted to.
@param stack   a Stack (Deque) used to support graph traversal.
@return Java object converted from the passed in object o, or if there is no custom reader.