class COSObject extends COSBase implements COSUpdateInfo
{
    private COSBase baseObject;
    private ICOSParser parser;
    private boolean isDereferenced = false;
    private final COSUpdateState updateState;
    
    private static final Logger LOG = LogManager.getLogger(COSObject.class);

    /**
     * Constructor.
     *
     * @param object The object that this encapsulates.
     *
     */
    public COSObject(COSBase object)
    {
        updateState = new COSUpdateState(this);
        baseObject = object;
        isDereferenced = true;
    }

    /**
     * Constructor.
     *
     * @param object The object that this encapsulates.
     * @param objectKey The COSObjectKey of the encapsulated object
     */
    public COSObject(COSBase object, COSObjectKey objectKey)
    {
        this(objectKey, null);
        baseObject = object;
        isDereferenced = true;
    }

    /**
     * Constructor.
     *
     * @param object The object that this encapsulates.
     * @param parser The parser to be used to load the object on demand
     *
     */
    public COSObject(COSBase object, ICOSParser parser)
    {
        updateState = new COSUpdateState(this);
        baseObject = object;
        isDereferenced = object != null;
        this.parser = parser;
    }

    /**
     * Constructor.
     *
     * @param key The object number of the encapsulated object.
     * @param parser The parser to be used to load the object on demand
     *
     */
    public COSObject(COSObjectKey key, ICOSParser parser)
    {
        updateState = new COSUpdateState(this);
        this.parser = parser;
        setKey(key);
    }

    /**
     * Indicates if the referenced object is present or not.
     * 
     * @return true if the indirect object is dereferenced
     */
    public boolean isObjectNull()
    {
        return baseObject == null;
    }

    /**
     * This will get the object that this object encapsulates.
     *
     * @return The encapsulated object.
     */
    public COSBase getObject()
    {<FILL_FUNCTION_BODY>}

    /**
     * Sets the referenced object to COSNull and removes the initially assigned parser.
     */
    public final void setToNull()
    {
        if(baseObject != null)
        {
            getUpdateState().update();
        }
        baseObject = COSNull.NULL;
        parser = null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString()
    {
		return "COSObject{" + getKey() + "}";
    }

    /**
     * visitor pattern double dispatch method.
     *
     * @param visitor The object to notify when visiting this object.
     * @throws IOException If an error occurs while visiting this object.
     */
    @Override
    public void accept( ICOSVisitor visitor ) throws IOException
    {
        COSBase object = getObject();
        if (object != null)
        {
            object.accept(visitor);
        }
        else
        {
            COSNull.NULL.accept(visitor);
        }
    }

    /**
     * Returns {@code true}, if the hereby referenced {@link COSBase} has already been parsed and loaded.
     *
     * @return {@code true}, if the hereby referenced {@link COSBase} has already been parsed and loaded.
     */
    public boolean isDereferenced()
    {
        return isDereferenced;
    }
    
    /**
     * Returns the current {@link COSUpdateState} of this {@link COSObject}.
     *
     * @return The current {@link COSUpdateState} of this {@link COSObject}.
     * @see COSUpdateState
     */
    @Override
    public COSUpdateState getUpdateState()
    {
        return updateState;
    }
    
}

        if (!isDereferenced && parser != null)
        {
            try
            {
                // mark as dereferenced to avoid endless recursions
                isDereferenced = true;
                baseObject = parser.dereferenceCOSObject(this);
                getUpdateState().dereferenceChild(baseObject);
            }
            catch (IOException e)
            {
                LOG.error("Can't dereference {}", this, e);
            }
            finally
            {
                parser = null;
            }
        }
        return baseObject;
    
<methods>public void <init>() ,public abstract void accept(org.apache.pdfbox.cos.ICOSVisitor) throws java.io.IOException,public org.apache.pdfbox.cos.COSBase getCOSObject() ,public org.apache.pdfbox.cos.COSObjectKey getKey() ,public boolean isDirect() ,public void setDirect(boolean) ,public void setKey(org.apache.pdfbox.cos.COSObjectKey) <variables>private boolean direct,private org.apache.pdfbox.cos.COSObjectKey key