private void FlushOrRelease(PdfObject obj)
 {
     if (release)
     {
         if (!obj.IsReleaseForbidden())
         {
             obj.Release();
         }
     }
     else
     {
         MakeIndirectIfNeeded(obj);
         if (!pdfDoc.IsAppendMode() || obj.IsModified())
         {
             obj.Flush();
         }
         else
         {
             if (!obj.IsReleaseForbidden())
             {
                 obj.Release();
             }
         }
     }
 }
        private void FlushObjectRecursively(PdfObject obj, PageFlushingHelper.DeepFlushingContext context)
        {
            if (obj == null)
            {
                return;
            }
            bool avoidReleaseForIndirectObjInstance = false;

            if (obj.IsIndirectReference())
            {
                PdfIndirectReference indRef = (PdfIndirectReference)obj;
                if (indRef.refersTo == null || indRef.CheckState(PdfObject.FLUSHED))
                {
                    return;
                }
                obj = indRef.GetRefersTo();
            }
            else
            {
                if (obj.IsFlushed())
                {
                    return;
                }
                else
                {
                    if (release && obj.IsIndirect())
                    {
                        // We should avoid the case when object is going to be released but is stored in containing object
                        // not as indirect reference. This can happen when containing object is somehow modified.
                        // Generally containing objects should not contain released read-only object instance.
                        System.Diagnostics.Debug.Assert(obj.IsReleaseForbidden() || obj.GetIndirectReference() == null);
                        avoidReleaseForIndirectObjInstance = true;
                    }
                }
            }
            if (pdfDoc.IsDocumentFont(obj.GetIndirectReference()) || layersRefs.Contains(obj.GetIndirectReference()))
            {
                return;
            }
            if (obj.IsDictionary() || obj.IsStream())
            {
                if (!currNestedObjParents.Add(obj))
                {
                    return;
                }
                FlushDictRecursively((PdfDictionary)obj, context);
                currNestedObjParents.Remove(obj);
            }
            else
            {
                if (obj.IsArray())
                {
                    if (!currNestedObjParents.Add(obj))
                    {
                        return;
                    }
                    PdfArray array = (PdfArray)obj;
                    for (int i = 0; i < array.Size(); ++i)
                    {
                        FlushObjectRecursively(array.Get(i, false), context);
                    }
                    currNestedObjParents.Remove(obj);
                }
            }
            if (!avoidReleaseForIndirectObjInstance)
            {
                FlushOrRelease(obj);
            }
        }