Class AcroFields


  • public class AcroFields
    extends java.lang.Object
    Query and change fields in existing documents either by method calls or by FDF merging.
    • Field Detail

      • FIELD_TYPE_NONE

        public static final int FIELD_TYPE_NONE
        A field type invalid or not found.
        See Also:
        Constant Field Values
      • FIELD_TYPE_PUSHBUTTON

        public static final int FIELD_TYPE_PUSHBUTTON
        A field type.
        See Also:
        Constant Field Values
      • FIELD_TYPE_CHECKBOX

        public static final int FIELD_TYPE_CHECKBOX
        A field type.
        See Also:
        Constant Field Values
      • FIELD_TYPE_RADIOBUTTON

        public static final int FIELD_TYPE_RADIOBUTTON
        A field type.
        See Also:
        Constant Field Values
      • FIELD_TYPE_COMBO

        public static final int FIELD_TYPE_COMBO
        A field type.
        See Also:
        Constant Field Values
      • FIELD_TYPE_SIGNATURE

        public static final int FIELD_TYPE_SIGNATURE
        A field type.
        See Also:
        Constant Field Values
      • stdFieldFontNames

        private static final java.util.HashMap<java.lang.String,​java.lang.String[]> stdFieldFontNames
      • buttonRemove

        private static final PdfName[] buttonRemove
      • topFirst

        private int topFirst
      • sigNames

        private java.util.HashMap<java.lang.String,​int[]> sigNames
      • append

        private boolean append
      • extensionFonts

        private java.util.HashMap<java.lang.Integer,​BaseFont> extensionFonts
      • lastWasString

        private boolean lastWasString
      • generateAppearances

        private boolean generateAppearances
        Holds value of property generateAppearances.
      • localFonts

        private java.util.HashMap<java.lang.String,​BaseFont> localFonts
      • extraMarginLeft

        private float extraMarginLeft
      • extraMarginTop

        private float extraMarginTop
      • substitutionFonts

        private java.util.ArrayList<BaseFont> substitutionFonts
      • orderedSignatureNames

        private java.util.ArrayList<java.lang.String> orderedSignatureNames
      • totalRevisions

        private int totalRevisions
        Holds value of property totalRevisions.
      • fieldCache

        private java.util.Map<java.lang.String,​TextField> fieldCache
        Holds value of property fieldCache.
        Since:
        2.1.5 this used to be a HashMap
    • Method Detail

      • splitDAelements

        public static java.lang.Object[] splitDAelements​(java.lang.String da)
      • clearSigDic

        private static void clearSigDic​(PdfDictionary dic)
      • fill

        void fill()
      • getAppearanceStates

        public java.lang.String[] getAppearanceStates​(java.lang.String fieldName)
        Gets the list of appearance names. Use it to get the names allowed with radio and checkbox fields. If the /Opt key exists the values will also be included. The name 'Off' may also be valid even if not returned in the list.

        For Comboboxes it will return an array of display values. To extract the export values of a Combobox, please refer to getListOptionExport(String)

        Parameters:
        fieldName - the fully qualified field name
        Returns:
        the list of names or null if the field does not exist
      • getListOption

        private java.lang.String[] getListOption​(java.lang.String fieldName,
                                                 int idx)
      • getListOptionExport

        public java.lang.String[] getListOptionExport​(java.lang.String fieldName)
        Gets the list of export option values from fields of type list or combo. If the field doesn't exist or the field type is not list or combo it will return null.
        Parameters:
        fieldName - the field name
        Returns:
        the list of export option values from fields of type list or combo
      • getListOptionDisplay

        public java.lang.String[] getListOptionDisplay​(java.lang.String fieldName)
        Gets the list of display option values from fields of type list or combo. If the field doesn't exist or the field type is not list or combo it will return null.
        Parameters:
        fieldName - the field name
        Returns:
        the list of export option values from fields of type list or combo
      • setListOption

        public boolean setListOption​(java.lang.String fieldName,
                                     java.lang.String[] exportValues,
                                     java.lang.String[] displayValues)
        Sets the option list for fields of type list or combo. One of exportValues or displayValues may be null but not both. This method will only set the list but will not set the value or appearance. For that, calling setField() is required.

        An example:

         PdfReader pdf = new PdfReader("input.pdf");
         PdfStamper stp = new PdfStamper(pdf, new FileOutputStream("output.pdf"));
         AcroFields af = stp.getAcroFields();
         af.setListOption("ComboBox", new String[]{"a", "b", "c"}, new String[]{"first", "second", "third"});
         af.setField("ComboBox", "b");
         stp.close();
         
        Parameters:
        fieldName - the field name
        exportValues - the export values
        displayValues - the display values
        Returns:
        true if the operation succeeded, false otherwise
      • getFieldType

        public int getFieldType​(java.lang.String fieldName)
        Gets the field type. The type can be one of: FIELD_TYPE_PUSHBUTTON, FIELD_TYPE_CHECKBOX, FIELD_TYPE_RADIOBUTTON, FIELD_TYPE_TEXT, FIELD_TYPE_LIST, FIELD_TYPE_COMBO or FIELD_TYPE_SIGNATURE.

        If the field does not exist or is invalid it returns FIELD_TYPE_NONE.

        Parameters:
        fieldName - the field name
        Returns:
        the field type
      • exportAsFdf

        public void exportAsFdf​(FdfWriter writer)
        Export the fields as a FDF.
        Parameters:
        writer - the FDF writer
      • renameField

        public boolean renameField​(java.lang.String oldName,
                                   java.lang.String newName)
        Renames a field. Only the last part of the name can be renamed. For example, if the original field is "ab.cd.ef" only the "ef" part can be renamed.
        Parameters:
        oldName - the old field name
        newName - the new field name
        Returns:
        true if the renaming was successful, false otherwise
      • getFieldRichValue

        public java.lang.String getFieldRichValue​(java.lang.String name)
        Retrieve the rich value for the given field
        Parameters:
        name -
        Returns:
        The rich value if present, or null.
        Since:
        5.0.6
      • getField

        public java.lang.String getField​(java.lang.String name)
        Gets the field value.
        Parameters:
        name - the fully qualified field name
        Returns:
        the field value
      • getListSelection

        public java.lang.String[] getListSelection​(java.lang.String name)
        Gets the field values of a Choice field.
        Parameters:
        name - the fully qualified field name
        Returns:
        the field value
        Since:
        2.1.3
      • setFieldProperty

        public boolean setFieldProperty​(java.lang.String field,
                                        java.lang.String name,
                                        java.lang.Object value,
                                        int[] inst)
        Sets a field property. Valid property names are:

        • textfont - sets the text font. The value for this entry is a BaseFont.
        • textcolor - sets the text color. The value for this entry is a BaseColor.
        • textsize - sets the text size. The value for this entry is a Float.
        • bgcolor - sets the background color. The value for this entry is a BaseColor. If null removes the background.
        • bordercolor - sets the border color. The value for this entry is a BaseColor. If null removes the border.
        Parameters:
        field - the field name
        name - the property name
        value - the property value
        inst - an array of int indexing into AcroField.Item.merged elements to process. Set to null to process all
        Returns:
        true if the property exists, false otherwise
      • setFieldProperty

        public boolean setFieldProperty​(java.lang.String field,
                                        java.lang.String name,
                                        int value,
                                        int[] inst)
        Sets a field property. Valid property names are:

        • flags - a set of flags specifying various characteristics of the field's widget annotation. The value of this entry replaces that of the F entry in the form's corresponding annotation dictionary.
        • setflags - a set of flags to be set (turned on) in the F entry of the form's corresponding widget annotation dictionary. Bits equal to 1 cause the corresponding bits in F to be set to 1.
        • clrflags - a set of flags to be cleared (turned off) in the F entry of the form's corresponding widget annotation dictionary. Bits equal to 1 cause the corresponding bits in F to be set to 0.
        • fflags - a set of flags specifying various characteristics of the field. The value of this entry replaces that of the Ff entry in the form's corresponding field dictionary.
        • setfflags - a set of flags to be set (turned on) in the Ff entry of the form's corresponding field dictionary. Bits equal to 1 cause the corresponding bits in Ff to be set to 1.
        • clrfflags - a set of flags to be cleared (turned off) in the Ff entry of the form's corresponding field dictionary. Bits equal to 1 cause the corresponding bits in Ff to be set to 0.
        Parameters:
        field - the field name
        name - the property name
        value - the property value
        inst - an array of int indexing into AcroField.Item.merged elements to process. Set to null to process all
        Returns:
        true if the property exists, false otherwise
      • mergeXfaData

        public void mergeXfaData​(org.w3c.dom.Node n)
                          throws java.io.IOException,
                                 DocumentException
        Merges an XML data structure into this form.
        Parameters:
        n - the top node of the data structure
        Throws:
        java.io.IOException - on error
        DocumentException - o error
      • setFields

        public void setFields​(FdfReader fdf)
                       throws java.io.IOException,
                              DocumentException
        Sets the fields by FDF merging.
        Parameters:
        fdf - the FDF form
        Throws:
        java.io.IOException - on error
        DocumentException - on error
      • regenerateField

        public boolean regenerateField​(java.lang.String name)
                                throws java.io.IOException,
                                       DocumentException
        Regenerates the field appearance. This is useful when you change a field property, but not its value, for instance form.setFieldProperty("f", "bgcolor", BaseColor.BLUE, null); This won't have any effect, unless you use regenerateField("f") after changing the property.
        Parameters:
        name - the fully qualified field name or the partial name in the case of XFA forms
        Returns:
        true if the field was found and changed, false otherwise
        Throws:
        java.io.IOException - on error
        DocumentException - on error
      • setField

        public boolean setField​(java.lang.String name,
                                java.lang.String value)
                         throws java.io.IOException,
                                DocumentException
        Sets the field value.
        Parameters:
        name - the fully qualified field name or the partial name in the case of XFA forms
        value - the field value
        Returns:
        true if the field was found and changed, false otherwise
        Throws:
        java.io.IOException - on error
        DocumentException - on error
      • setField

        public boolean setField​(java.lang.String name,
                                java.lang.String value,
                                boolean saveAppearance)
                         throws java.io.IOException,
                                DocumentException
        Sets the field value.
        Parameters:
        name - the fully qualified field name or the partial name in the case of XFA forms
        value - the field value
        saveAppearance - save the current appearance of the field or not
        Returns:
        true if the field was found and changed, false otherwise
        Throws:
        java.io.IOException - on error
        DocumentException - on error
      • setFieldRichValue

        public boolean setFieldRichValue​(java.lang.String name,
                                         java.lang.String richValue)
                                  throws DocumentException,
                                         java.io.IOException
        Sets the rich value for the given field. See PDF Reference chapter 12.7.3.4 (Rich Text) and 12.7.4.3 (Text Fields) for further details. Note that iText doesn't create an appearance for Rich Text fields. So you either need to use XML Worker to create an appearance (/N entry in the /AP dictionary), or you need to use setGenerateAppearances(false) to tell the viewer that iText didn't create any appearances.
        Parameters:
        name - Field name
        richValue - html markup
        Returns:
        success/failure (will fail if the field isn't found, isn't a text field, or doesn't support rich text)
        Throws:
        DocumentException
        java.io.IOException
        Since:
        5.0.6
      • setField

        public boolean setField​(java.lang.String name,
                                java.lang.String value,
                                java.lang.String display)
                         throws java.io.IOException,
                                DocumentException
        Sets the field value and the display string. The display string is used to build the appearance in the cases where the value is modified by Acrobat with JavaScript and the algorithm is known.
        Parameters:
        name - the fully qualified field name or the partial name in the case of XFA forms
        value - the field value
        display - the string that is used for the appearance. If null the value parameter will be used
        Returns:
        true if the field was found and changed, false otherwise
        Throws:
        java.io.IOException - on error
        DocumentException - on error
      • setField

        public boolean setField​(java.lang.String name,
                                java.lang.String value,
                                java.lang.String display,
                                boolean saveAppearance)
                         throws java.io.IOException,
                                DocumentException
        Sets the field value and the display string. The display string is used to build the appearance in the cases where the value is modified by Acrobat with JavaScript and the algorithm is known.
        Parameters:
        name - the fully qualified field name or the partial name in the case of XFA forms
        value - the field value
        display - the string that is used for the appearance. If null the value parameter will be used
        saveAppearance - save the current appearance of the field or not
        Returns:
        true if the field was found and changed, false otherwise
        Throws:
        java.io.IOException - on error
        DocumentException - on error
      • setListSelection

        public boolean setListSelection​(java.lang.String name,
                                        java.lang.String[] value)
                                 throws java.io.IOException,
                                        DocumentException
        Sets different values in a list selection. No appearance is generated yet; nor does the code check if multiple select is allowed.
        Parameters:
        name - the name of the field
        value - an array with values that need to be selected
        Returns:
        true only if the field value was changed
        Throws:
        java.io.IOException
        DocumentException
        Since:
        2.1.4
      • getFields

        public java.util.Map<java.lang.String,​AcroFields.Item> getFields()
        Gets all the fields. The fields are keyed by the fully qualified field name and the value is an instance of AcroFields.Item.
        Returns:
        all the fields
      • setFields

        public void setFields​(XfdfReader xfdf)
                       throws java.io.IOException,
                              DocumentException
        Sets the fields by XFDF merging.
        Parameters:
        xfdf - the XFDF form
        Throws:
        java.io.IOException - on error
        DocumentException - on error
      • getFieldItem

        public AcroFields.Item getFieldItem​(java.lang.String name)
        Gets the field structure.
        Parameters:
        name - the name of the field
        Returns:
        the field structure or null if the field does not exist
      • getTranslatedFieldName

        public java.lang.String getTranslatedFieldName​(java.lang.String name)
        Gets the long XFA translated name.
        Parameters:
        name - the name of the field
        Returns:
        the long field name
      • getFieldPositions

        public java.util.List<AcroFields.FieldPosition> getFieldPositions​(java.lang.String name)
        Gets the field box positions in the document. The return is an array of float multiple of 5. For each of this groups the values are: [page, llx, lly, urx, ury]. The coordinates have the page rotation in consideration.
        Parameters:
        name - the field name
        Returns:
        the positions or null if field does not exist
      • removeRefFromArray

        private int removeRefFromArray​(PdfArray array,
                                       PdfObject refo)
      • removeFieldsFromPage

        public boolean removeFieldsFromPage​(int page)
        Removes all the fields from page.
        Parameters:
        page - the page to remove the fields from
        Returns:
        true if any field was removed, false otherwise
      • removeField

        public boolean removeField​(java.lang.String name,
                                   int page)
        Removes a field from the document. If page equals -1 all the fields with this name are removed from the document otherwise only the fields in that particular page are removed.
        Parameters:
        name - the field name
        page - the page to remove the field from or -1 to remove it from all the pages
        Returns:
        true if the field exists, false otherwise
      • removeField

        public boolean removeField​(java.lang.String name)
        Removes a field from the document.
        Parameters:
        name - the field name
        Returns:
        true if the field exists, false otherwise
      • isGenerateAppearances

        public boolean isGenerateAppearances()
        Gets the property generateAppearances.
        Returns:
        the property generateAppearances
      • setGenerateAppearances

        public void setGenerateAppearances​(boolean generateAppearances)
        Sets the option to generate appearances. Not generating appearances will speed-up form filling but the results can be unexpected in Acrobat. Don't use it unless your environment is well controlled. The default is true.
        Parameters:
        generateAppearances - the option to generate appearances
      • clearSignatureField

        public boolean clearSignatureField​(java.lang.String name)
        Clears a signed field.
        Parameters:
        name - the field name
        Returns:
        true if the field was signed, false if the field was not signed or not found
        Since:
        5.0.5
      • getSignatureNames

        public java.util.ArrayList<java.lang.String> getSignatureNames()
        Gets the field names that have signatures and are signed.
        Returns:
        the field names that have signatures and are signed
      • getBlankSignatureNames

        public java.util.ArrayList<java.lang.String> getBlankSignatureNames()
        Gets the field names that have blank signatures.
        Returns:
        the field names that have blank signatures
      • getSignatureDictionary

        public PdfDictionary getSignatureDictionary​(java.lang.String name)
        Gets the signature dictionary, the one keyed by /V.
        Parameters:
        name - the field name
        Returns:
        the signature dictionary keyed by /V or null if the field is not a signature
      • getNormalAppearance

        public PdfIndirectReference getNormalAppearance​(java.lang.String name)
        Gets a reference to the normal appearance of a field.
        Parameters:
        name - the field name
        Returns:
        a reference to the /N entry of the /AP dictionary or null if the field is not found
      • signatureCoversWholeDocument

        public boolean signatureCoversWholeDocument​(java.lang.String name)
        Checks is the signature covers the entire document or just part of it.
        Parameters:
        name - the signature field name
        Returns:
        true if the signature covers the entire document, false otherwise
      • verifySignature

        public PdfPKCS7 verifySignature​(java.lang.String name)
        Verifies a signature. An example usage is:

         KeyStore kall = PdfPKCS7.loadCacertsKeyStore();
         PdfReader reader = new PdfReader("my_signed_doc.pdf");
         AcroFields af = reader.getAcroFields();
         ArrayList names = af.getSignatureNames();
         for (int k = 0; k < names.size(); ++k) {
            String name = (String)names.get(k);
            System.out.println("Signature name: " + name);
            System.out.println("Signature covers whole document: " + af.signatureCoversWholeDocument(name));
            PdfPKCS7 pk = af.verifySignature(name);
            Calendar cal = pk.getSignDate();
            Certificate pkc[] = pk.getCertificates();
            System.out.println("Subject: " + PdfPKCS7.getSubjectFields(pk.getSigningCertificate()));
            System.out.println("Document modified: " + !pk.verify());
            Object fails[] = PdfPKCS7.verifyCertificates(pkc, kall, null, cal);
            if (fails == null)
                System.out.println("Certificates verified against the KeyStore");
            else
                System.out.println("Certificate failed: " + fails[1]);
         }
         
        Parameters:
        name - the signature field name
        Returns:
        a PdfPKCS7 class to continue the verification
      • verifySignature

        public PdfPKCS7 verifySignature​(java.lang.String name,
                                        java.lang.String provider)
        Verifies a signature. An example usage is:

         KeyStore kall = PdfPKCS7.loadCacertsKeyStore();
         PdfReader reader = new PdfReader("my_signed_doc.pdf");
         AcroFields af = reader.getAcroFields();
         ArrayList names = af.getSignatureNames();
         for (int k = 0; k < names.size(); ++k) {
            String name = (String)names.get(k);
            System.out.println("Signature name: " + name);
            System.out.println("Signature covers whole document: " + af.signatureCoversWholeDocument(name));
            PdfPKCS7 pk = af.verifySignature(name);
            Calendar cal = pk.getSignDate();
            Certificate pkc[] = pk.getCertificates();
            System.out.println("Subject: " + PdfPKCS7.getSubjectFields(pk.getSigningCertificate()));
            System.out.println("Document modified: " + !pk.verify());
            Object fails[] = PdfPKCS7.verifyCertificates(pkc, kall, null, cal);
            if (fails == null)
                System.out.println("Certificates verified against the KeyStore");
            else
                System.out.println("Certificate failed: " + fails[1]);
         }
         
        Parameters:
        name - the signature field name
        provider - the provider or null for the default provider
        Returns:
        a PdfPKCS7 class to continue the verification
      • markUsed

        private void markUsed​(PdfObject obj)
      • getTotalRevisions

        public int getTotalRevisions()
        Gets the total number of revisions this document has.
        Returns:
        the total number of revisions
      • getRevision

        public int getRevision​(java.lang.String field)
        Gets this field revision.
        Parameters:
        field - the signature field name
        Returns:
        the revision or zero if it's not a signature field
      • extractRevision

        public java.io.InputStream extractRevision​(java.lang.String field)
                                            throws java.io.IOException
        Extracts a revision from the document.
        Parameters:
        field - the signature field name
        Returns:
        an InputStream covering the revision. Returns null if it's not a signature field
        Throws:
        java.io.IOException - on error
      • getFieldCache

        public java.util.Map<java.lang.String,​TextField> getFieldCache()
        Gets the appearances cache.
        Returns:
        the appearances cache
        Since:
        2.1.5 this method used to return a HashMap
      • setFieldCache

        public void setFieldCache​(java.util.Map<java.lang.String,​TextField> fieldCache)
        Sets a cache for field appearances. Parsing the existing PDF to create a new TextField is time expensive. For those tasks that repeatedly fill the same PDF with different field values the use of the cache has dramatic speed advantages. An example usage:

         String pdfFile = ...;// the pdf file used as template
         ArrayList xfdfFiles = ...;// the xfdf file names
         ArrayList pdfOutFiles = ...;// the output file names, one for each element in xpdfFiles
         HashMap cache = new HashMap();// the appearances cache
         PdfReader originalReader = new PdfReader(pdfFile);
         for (int k = 0; k < xfdfFiles.size(); ++k) {
            PdfReader reader = new PdfReader(originalReader);
            XfdfReader xfdf = new XfdfReader((String)xfdfFiles.get(k));
            PdfStamper stp = new PdfStamper(reader, new FileOutputStream((String)pdfOutFiles.get(k)));
            AcroFields af = stp.getAcroFields();
            af.setFieldCache(cache);
            af.setFields(xfdf);
            stp.close();
         }
         
        Parameters:
        fieldCache - a Map that will carry the cached appearances
        Since:
        2.1.5 this method used to take a HashMap as parameter
      • setExtraMargin

        public void setExtraMargin​(float extraMarginLeft,
                                   float extraMarginTop)
        Sets extra margins in text fields to better mimic the Acrobat layout.
        Parameters:
        extraMarginLeft - the extra margin left
        extraMarginTop - the extra margin top
      • addSubstitutionFont

        public void addSubstitutionFont​(BaseFont font)
        Adds a substitution font to the list. The fonts in this list will be used if the original font doesn't contain the needed glyphs.
        Parameters:
        font - the font
      • getSubstitutionFonts

        public java.util.ArrayList<BaseFont> getSubstitutionFonts()
        Gets the list of substitution fonts. The list is composed of BaseFont and can be null. The fonts in this list will be used if the original font doesn't contain the needed glyphs.
        Returns:
        the list
      • setSubstitutionFonts

        public void setSubstitutionFonts​(java.util.ArrayList<BaseFont> substitutionFonts)
        Sets a list of substitution fonts. The list is composed of BaseFont and can also be null. The fonts in this list will be used if the original font doesn't contain the needed glyphs.
        Parameters:
        substitutionFonts - the list
      • getXfa

        public XfaForm getXfa()
        Gets the XFA form processor.
        Returns:
        the XFA form processor
      • removeXfa

        public void removeXfa()
        Removes the XFA stream from the document.
      • getNewPushbuttonFromField

        public PushbuttonField getNewPushbuttonFromField​(java.lang.String field)
        Creates a new pushbutton from an existing field. If there are several pushbuttons with the same name only the first one is used. This pushbutton can be changed and be used to replace an existing one, with the same name or other name, as long is it is in the same document. To replace an existing pushbutton call replacePushbuttonField(String, PdfFormField).
        Parameters:
        field - the field name that should be a pushbutton
        Returns:
        a new pushbutton or null if the field is not a pushbutton
      • getNewPushbuttonFromField

        public PushbuttonField getNewPushbuttonFromField​(java.lang.String field,
                                                         int order)
        Creates a new pushbutton from an existing field. This pushbutton can be changed and be used to replace an existing one, with the same name or other name, as long is it is in the same document. To replace an existing pushbutton call replacePushbuttonField(String, PdfFormField, int).
        Parameters:
        field - the field name that should be a pushbutton
        order - the field order in fields with same name
        Returns:
        a new pushbutton or null if the field is not a pushbutton
        Since:
        2.0.7
      • replacePushbuttonField

        public boolean replacePushbuttonField​(java.lang.String field,
                                              PdfFormField button)
        Replaces the first field with a new pushbutton. The pushbutton can be created with getNewPushbuttonFromField(String) from the same document or it can be a generic PdfFormField of the type pushbutton.
        Parameters:
        field - the field name
        button - the PdfFormField representing the pushbutton
        Returns:
        true if the field was replaced, false if the field was not a pushbutton
      • replacePushbuttonField

        public boolean replacePushbuttonField​(java.lang.String field,
                                              PdfFormField button,
                                              int order)
        Replaces the designated field with a new pushbutton. The pushbutton can be created with getNewPushbuttonFromField(String, int) from the same document or it can be a generic PdfFormField of the type pushbutton.
        Parameters:
        field - the field name
        button - the PdfFormField representing the pushbutton
        order - the field order in fields with same name
        Returns:
        true if the field was replaced, false if the field was not a pushbutton
        Since:
        2.0.7
      • doesSignatureFieldExist

        public boolean doesSignatureFieldExist​(java.lang.String name)
        Checks whether a name exists as a signature field or not. It checks both signed fields and blank signatures.
        Parameters:
        name - String
        Returns:
        boolean does the signature field exist
        Since:
        5.5.1