Modified: poi/trunk/src/java/org/apache/poi/hssf/record/chart/UnitsRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/chart/UnitsRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/chart/UnitsRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/chart/UnitsRecord.java Sun 
Apr 12 22:03:52 2020
@@ -17,9 +17,13 @@
 
 package org.apache.poi.hssf.record.chart;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.hssf.record.HSSFRecordTypes;
 import org.apache.poi.hssf.record.RecordInputStream;
 import org.apache.poi.hssf.record.StandardRecord;
-import org.apache.poi.util.HexDump;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.Removal;
 
@@ -42,20 +46,6 @@ public final class UnitsRecord extends S
         field_1_units = in.readShort();
     }
 
-    public String toString()
-    {
-        StringBuilder buffer = new StringBuilder();
-
-        buffer.append("[UNITS]\n");
-        buffer.append("    .units                = ")
-            .append("0x").append(HexDump.toHex(  getUnits ()))
-            .append(" (").append( getUnits() ).append(" )");
-        buffer.append(System.getProperty("line.separator"));
-
-        buffer.append("[/UNITS]\n");
-        return buffer.toString();
-    }
-
     public void serialize(LittleEndianOutput out) {
         out.writeShort(field_1_units);
     }
@@ -70,7 +60,7 @@ public final class UnitsRecord extends S
     }
 
     @Override
-    @SuppressWarnings("squid:S2975")
+    @SuppressWarnings({"squid:S2975", "MethodDoesntCallSuperMethod"})
     @Deprecated
     @Removal(version = "5.0.0")
     public UnitsRecord clone() {
@@ -97,4 +87,14 @@ public final class UnitsRecord extends S
     {
         this.field_1_units = field_1_units;
     }
+
+    @Override
+    public HSSFRecordTypes getGenericRecordType() {
+        return HSSFRecordTypes.UNITS;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties("units", this::getUnits);
+    }
 }

Modified: 
poi/trunk/src/java/org/apache/poi/hssf/record/chart/ValueRangeRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/chart/ValueRangeRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/chart/ValueRangeRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/chart/ValueRangeRecord.java 
Sun Apr 12 22:03:52 2020
@@ -17,11 +17,15 @@
 
 package org.apache.poi.hssf.record.chart;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.hssf.record.HSSFRecordTypes;
 import org.apache.poi.hssf.record.RecordInputStream;
 import org.apache.poi.hssf.record.StandardRecord;
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
-import org.apache.poi.util.HexDump;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.Removal;
 
@@ -69,44 +73,6 @@ public final class ValueRangeRecord exte
         field_6_options           = in.readShort();
     }
 
-    public String toString()
-    {
-        StringBuilder buffer = new StringBuilder();
-
-        buffer.append("[VALUERANGE]\n");
-        buffer.append("    .minimumAxisValue     = ")
-            .append(" (").append( getMinimumAxisValue() ).append(" )");
-        buffer.append(System.getProperty("line.separator"));
-        buffer.append("    .maximumAxisValue     = ")
-            .append(" (").append( getMaximumAxisValue() ).append(" )");
-        buffer.append(System.getProperty("line.separator"));
-        buffer.append("    .majorIncrement       = ")
-            .append(" (").append( getMajorIncrement() ).append(" )");
-        buffer.append(System.getProperty("line.separator"));
-        buffer.append("    .minorIncrement       = ")
-            .append(" (").append( getMinorIncrement() ).append(" )");
-        buffer.append(System.getProperty("line.separator"));
-        buffer.append("    .categoryAxisCross    = ")
-            .append(" (").append( getCategoryAxisCross() ).append(" )");
-        buffer.append(System.getProperty("line.separator"));
-        buffer.append("    .options              = ")
-            .append("0x").append(HexDump.toHex(  getOptions ()))
-            .append(" (").append( getOptions() ).append(" )");
-        buffer.append(System.getProperty("line.separator"));
-        buffer.append("         .automaticMinimum         = 
").append(isAutomaticMinimum()).append('\n');
-        buffer.append("         .automaticMaximum         = 
").append(isAutomaticMaximum()).append('\n');
-        buffer.append("         .automaticMajor           = 
").append(isAutomaticMajor()).append('\n');
-        buffer.append("         .automaticMinor           = 
").append(isAutomaticMinor()).append('\n');
-        buffer.append("         .automaticCategoryCrossing     = 
").append(isAutomaticCategoryCrossing()).append('\n');
-        buffer.append("         .logarithmicScale         = 
").append(isLogarithmicScale()).append('\n');
-        buffer.append("         .valuesInReverse          = 
").append(isValuesInReverse()).append('\n');
-        buffer.append("         .crossCategoryAxisAtMaximum     = 
").append(isCrossCategoryAxisAtMaximum()).append('\n');
-        buffer.append("         .reserved                 = 
").append(isReserved()).append('\n');
-
-        buffer.append("[/VALUERANGE]\n");
-        return buffer.toString();
-    }
-
     public void serialize(LittleEndianOutput out) {
         out.writeDouble(field_1_minimumAxisValue);
         out.writeDouble(field_2_maximumAxisValue);
@@ -126,7 +92,7 @@ public final class ValueRangeRecord exte
     }
 
     @Override
-    @SuppressWarnings("squid:S2975")
+    @SuppressWarnings({"squid:S2975", "MethodDoesntCallSuperMethod"})
     @Deprecated
     @Removal(version = "5.0.0")
     public ValueRangeRecord clone() {
@@ -395,4 +361,23 @@ public final class ValueRangeRecord exte
     {
         return reserved.isSet(field_6_options);
     }
+
+    @Override
+    public HSSFRecordTypes getGenericRecordType() {
+        return HSSFRecordTypes.VALUE_RANGE;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "minimumAxisValue", this::getMinimumAxisValue,
+            "maximumAxisValue", this::getMaximumAxisValue,
+            "majorIncrement", this::getMajorIncrement,
+            "minorIncrement", this::getMinorIncrement,
+            "categoryAxisCross", this::getCategoryAxisCross,
+            "options", GenericRecordUtil.getBitsAsString(this::getOptions,
+                new BitField[]{automaticMinimum, automaticMaximum, 
automaticMajor, automaticMinor, automaticCategoryCrossing, logarithmicScale, 
valuesInReverse, crossCategoryAxisAtMaximum, reserved},
+                new String[]{"AUTOMATIC_MINIMUM", "AUTOMATIC_MAXIMUM", 
"AUTOMATIC_MAJOR", "AUTOMATIC_MINOR", "AUTOMATIC_CATEGORY_CROSSING", 
"LOGARITHMIC_SCALE", "VALUES_IN_REVERSE", "CROSS_CATEGORY_AXIS_AT_MAXIMUM", 
"RESERVED"})
+        );
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/common/ExtRst.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/common/ExtRst.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/common/ExtRst.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/common/ExtRst.java Sun Apr 12 
22:03:52 2020
@@ -18,9 +18,13 @@
 package org.apache.poi.hssf.record.common;
 
 import java.util.Arrays;
+import java.util.Map;
+import java.util.function.Supplier;
 import java.util.stream.Stream;
 
+import org.apache.poi.common.usermodel.GenericRecord;
 import org.apache.poi.hssf.record.cont.ContinuableRecordOutput;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.LittleEndianInput;
@@ -29,7 +33,7 @@ import org.apache.poi.util.POILogger;
 import org.apache.poi.util.StringUtil;
 
 @Internal
-public class ExtRst implements Comparable<ExtRst> {
+public class ExtRst implements Comparable<ExtRst>, GenericRecord {
     private static final POILogger _logger = 
POILogFactory.getLogger(ExtRst.class);
     //arbitrarily selected; may need to increase
     private static final int MAX_RECORD_LENGTH = 100_000;
@@ -157,8 +161,8 @@ public class ExtRst implements Comparabl
         out.writeContinueIfRequired(phoneticText.length()*2);
         StringUtil.putUnicodeLE(phoneticText, out);
 
-        for(int i=0; i<phRuns.length; i++) {
-            phRuns[i].serialize(out);
+        for (PhRun phRun : phRuns) {
+            phRun.serialize(out);
         }
 
         out.write(extraData);
@@ -245,4 +249,16 @@ public class ExtRst implements Comparabl
         return phRuns;
     }
 
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "reserved", () -> reserved,
+            "formattingFontIndex", this::getFormattingFontIndex,
+            "formattingOptions", this::getFormattingOptions,
+            "numberOfRuns", this::getNumberOfRuns,
+            "phoneticText", this::getPhoneticText,
+            "phRuns", this::getPhRuns,
+            "extraData", () -> extraData
+        );
+    }
 }

Modified: 
poi/trunk/src/java/org/apache/poi/hssf/record/common/FeatFormulaErr2.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/common/FeatFormulaErr2.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/common/FeatFormulaErr2.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/common/FeatFormulaErr2.java 
Sun Apr 12 22:03:52 2020
@@ -17,10 +17,17 @@
 
 package org.apache.poi.hssf.record.common;
 
+import static org.apache.poi.util.GenericRecordUtil.getBitsAsString;
+
+import java.util.Map;
+import java.util.function.Supplier;
+
 import org.apache.poi.hssf.record.FeatRecord;
 import org.apache.poi.hssf.record.RecordInputStream;
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.GenericRecordJsonWriter;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 
 /**
@@ -59,19 +66,17 @@ public final class FeatFormulaErr2 imple
                errorCheck = in.readInt();
        }
 
+       @Override
+       public Map<String, Supplier<?>> getGenericProperties() {
+               return GenericRecordUtil.getGenericProperties(
+                       "errorCheck", 
getBitsAsString(this::_getRawErrorCheckValue,
+                       new BitField[]{CHECK_CALCULATION_ERRORS, 
CHECK_EMPTY_CELL_REF, CHECK_NUMBERS_AS_TEXT, CHECK_INCONSISTENT_RANGES, 
CHECK_INCONSISTENT_FORMULAS, CHECK_DATETIME_FORMATS, 
CHECK_UNPROTECTED_FORMULAS, PERFORM_DATA_VALIDATION},
+                       new String[]{"CHECK_CALCULATION_ERRORS", 
"CHECK_EMPTY_CELL_REF", "CHECK_NUMBERS_AS_TEXT", "CHECK_INCONSISTENT_RANGES", 
"CHECK_INCONSISTENT_FORMULAS", "CHECK_DATETIME_FORMATS", 
"CHECK_UNPROTECTED_FORMULAS", "PERFORM_DATA_VALIDATION"})
+               );
+       }
+
        public String toString() {
-               StringBuilder buffer = new StringBuilder();
-               buffer.append(" [FEATURE FORMULA ERRORS]\n");
-               buffer.append("  checkCalculationErrors    = ");
-               buffer.append("  checkEmptyCellRef         = ");
-               buffer.append("  checkNumbersAsText        = ");
-               buffer.append("  checkInconsistentRanges   = ");
-               buffer.append("  checkInconsistentFormulas = ");
-               buffer.append("  checkDateTimeFormats      = ");
-               buffer.append("  checkUnprotectedFormulas  = ");
-               buffer.append("  performDataValidation     = ");
-               buffer.append(" [/FEATURE FORMULA ERRORS]\n");
-               return buffer.toString();
+               return GenericRecordJsonWriter.marshal(this);
        }
 
        public void serialize(LittleEndianOutput out) {

Modified: 
poi/trunk/src/java/org/apache/poi/hssf/record/common/FeatProtection.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/common/FeatProtection.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/common/FeatProtection.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/common/FeatProtection.java 
Sun Apr 12 22:03:52 2020
@@ -17,10 +17,14 @@
 
 package org.apache.poi.hssf.record.common;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
 import org.apache.poi.hssf.record.FeatRecord;
 import org.apache.poi.hssf.record.PasswordRecord;
 import org.apache.poi.hssf.record.PasswordRev4Record;
 import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.StringUtil;
 
@@ -69,17 +73,6 @@ public final class FeatProtection implem
                securityDescriptor = in.readRemainder();
        }
 
-       public String toString() {
-               StringBuilder buffer = new StringBuilder();
-               buffer.append(" [FEATURE PROTECTION]\n");
-               buffer.append("   Self Relative = " + fSD);
-               buffer.append("   Password Verifier = " + passwordVerifier);
-               buffer.append("   Title = " + title);
-               buffer.append("   Security Descriptor Size = " + 
securityDescriptor.length);
-               buffer.append(" [/FEATURE PROTECTION]\n");
-               return buffer.toString();
-       }
-
        public void serialize(LittleEndianOutput out) {
                out.writeInt(fSD);
                out.writeInt(passwordVerifier);
@@ -105,6 +98,9 @@ public final class FeatProtection implem
                this.title = title;
        }
 
+       /**
+        * @return Self Relative
+        */
        public int getFSD() {
                return fSD;
        }
@@ -113,4 +109,14 @@ public final class FeatProtection implem
        public FeatProtection copy() {
                return new FeatProtection(this);
        }
+
+       @Override
+       public Map<String, Supplier<?>> getGenericProperties() {
+               return GenericRecordUtil.getGenericProperties(
+                       "FSD", this::getFSD,
+                       "passwordVerifier", this::getPasswordVerifier,
+                       "title", this::getTitle,
+                       "securityDescriptor", () -> securityDescriptor
+               );
+       }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/common/FeatSmartTag.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/common/FeatSmartTag.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/common/FeatSmartTag.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/common/FeatSmartTag.java Sun 
Apr 12 22:03:52 2020
@@ -17,8 +17,13 @@
 
 package org.apache.poi.hssf.record.common;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
 import org.apache.poi.hssf.record.FeatRecord;
 import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.util.GenericRecordJsonWriter;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 
 //import org.apache.poi.hssf.record.Feat11Record;
@@ -51,10 +56,7 @@ public final class FeatSmartTag implemen
        }
 
        public String toString() {
-               StringBuilder buffer = new StringBuilder();
-               buffer.append(" [FEATURE SMART TAGS]\n");
-               buffer.append(" [/FEATURE SMART TAGS]\n");
-               return buffer.toString();
+               return GenericRecordJsonWriter.marshal(this);
        }
 
        public int getDataSize() {
@@ -69,4 +71,9 @@ public final class FeatSmartTag implemen
        public FeatSmartTag copy() {
                return new FeatSmartTag(this);
        }
+
+       @Override
+       public Map<String, Supplier<?>> getGenericProperties() {
+               return GenericRecordUtil.getGenericProperties("data", () -> 
data);
+       }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/common/FormatRun.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/common/FormatRun.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/common/FormatRun.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/common/FormatRun.java Sun Apr 
12 22:03:52 2020
@@ -17,12 +17,17 @@
 
 package org.apache.poi.hssf.record.common;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.common.usermodel.GenericRecord;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
 
 @Internal
-public class FormatRun implements Comparable<FormatRun> {
+public class FormatRun implements Comparable<FormatRun>, GenericRecord {
     final short _character;
     short _fontIndex;
 
@@ -81,4 +86,12 @@ public class FormatRun implements Compar
         out.writeShort(_character);
         out.writeShort(_fontIndex);
     }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "characterPos", this::getCharacterPos,
+            "fontIndex", this::getFontIndex
+        );
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/common/FtrHeader.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/common/FtrHeader.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/common/FtrHeader.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/common/FtrHeader.java Sun Apr 
12 22:03:52 2020
@@ -17,9 +17,15 @@
 
 package org.apache.poi.hssf.record.common;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
 import org.apache.poi.common.Duplicatable;
+import org.apache.poi.common.usermodel.GenericRecord;
 import org.apache.poi.hssf.record.RecordInputStream;
 import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.util.GenericRecordJsonWriter;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.Removal;
 
@@ -30,7 +36,7 @@ import org.apache.poi.util.Removal;
  *  style record, which includes extra attributes above and
  *  beyond those of a traditional record.
  */
-public final class FtrHeader implements Duplicatable {
+public final class FtrHeader implements Duplicatable, GenericRecord {
     /** This MUST match the type on the containing record */
     private short recordType;
     /** This is a FrtFlags */
@@ -56,12 +62,7 @@ public final class FtrHeader implements
     }
 
     public String toString() {
-        StringBuilder buffer = new StringBuilder();
-        buffer.append(" [FUTURE HEADER]\n");
-        buffer.append("   Type " + recordType);
-        buffer.append("   Flags " + grbitFrt);
-        buffer.append(" [/FUTURE HEADER]\n");
-        return buffer.toString();
+        return GenericRecordJsonWriter.marshal(this);
     }
 
     public void serialize(LittleEndianOutput out) {
@@ -96,7 +97,7 @@ public final class FtrHeader implements
     }
 
     @Override
-    @SuppressWarnings("squid:S2975")
+    @SuppressWarnings({"squid:S2975", "MethodDoesntCallSuperMethod"})
     @Deprecated
     @Removal(version = "5.0.0")
     public FtrHeader clone() {
@@ -106,4 +107,13 @@ public final class FtrHeader implements
     public FtrHeader copy() {
         return new FtrHeader(this);
     }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "recordType", this::getRecordType,
+            "grbitFrt", this::getGrbitFrt,
+            "associatedRange", this::getAssociatedRange
+        );
+    }
 }
\ No newline at end of file

Modified: 
poi/trunk/src/java/org/apache/poi/hssf/record/common/SharedFeature.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/common/SharedFeature.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/common/SharedFeature.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/common/SharedFeature.java Sun 
Apr 12 22:03:52 2020
@@ -17,12 +17,13 @@
 
 package org.apache.poi.hssf.record.common;
 
+import org.apache.poi.common.usermodel.GenericRecord;
 import org.apache.poi.util.LittleEndianOutput;
 
 /**
  * Common Interface for all Shared Features
  */
-public interface SharedFeature {
+public interface SharedFeature extends GenericRecord {
        String toString();
        void serialize(LittleEndianOutput out);
        int getDataSize();

Modified: 
poi/trunk/src/java/org/apache/poi/hssf/record/common/UnicodeString.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/common/UnicodeString.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/common/UnicodeString.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/common/UnicodeString.java Sun 
Apr 12 22:03:52 2020
@@ -21,15 +21,19 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
+import java.util.function.Supplier;
 import java.util.stream.Collectors;
 
 import org.apache.poi.common.Duplicatable;
+import org.apache.poi.common.usermodel.GenericRecord;
 import org.apache.poi.hssf.record.RecordInputStream;
 import org.apache.poi.hssf.record.cont.ContinuableRecordInput;
 import org.apache.poi.hssf.record.cont.ContinuableRecordOutput;
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
 import org.apache.poi.util.Removal;
@@ -39,7 +43,7 @@ import org.apache.poi.util.Removal;
  * It is considered more desirable then repeating it in all of them.<p>
  * This is often called a XLUnicodeRichExtendedString in MS documentation.<p>
  */
-public class UnicodeString implements Comparable<UnicodeString>, Duplicatable {
+public class UnicodeString implements Comparable<UnicodeString>, Duplicatable, 
GenericRecord {
     private static final POILogger _logger = 
POILogFactory.getLogger(UnicodeString.class);
 
     private static final BitField highByte  = BitFieldFactory.getInstance(0x1);
@@ -505,4 +509,15 @@ public class UnicodeString implements Co
     public UnicodeString copy() {
         return new UnicodeString(this);
     }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "charCount", this::getCharCount,
+            "optionFlags", this::getOptionFlags,
+            "string", this::getString,
+            "formatRuns", () -> field_4_format_runs,
+            "extendedRst", this::getExtendedRst
+        );
+    }
 }

Modified: 
poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/DataItemRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/DataItemRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- 
poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/DataItemRecord.java 
(original)
+++ 
poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/DataItemRecord.java 
Sun Apr 12 22:03:52 2020
@@ -17,9 +17,13 @@
 
 package org.apache.poi.hssf.record.pivottable;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.hssf.record.HSSFRecordTypes;
 import org.apache.poi.hssf.record.RecordInputStream;
 import org.apache.poi.hssf.record.StandardRecord;
-import org.apache.poi.util.HexDump;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.StringUtil;
 
@@ -83,22 +87,24 @@ public final class DataItemRecord extend
        }
 
        @Override
-       public String toString() {
-               StringBuilder buffer = new StringBuilder();
+       public DataItemRecord copy() {
+               return new DataItemRecord(this);
+       }
 
-               buffer.append("[SXDI]\n");
-               buffer.append("  .isxvdData = 
").append(HexDump.shortToHex(isxvdData)).append("\n");
-               buffer.append("  .iiftab = 
").append(HexDump.shortToHex(iiftab)).append("\n");
-               buffer.append("  .df = 
").append(HexDump.shortToHex(df)).append("\n");
-               buffer.append("  .isxvd = 
").append(HexDump.shortToHex(isxvd)).append("\n");
-               buffer.append("  .isxvi = 
").append(HexDump.shortToHex(isxvi)).append("\n");
-               buffer.append("  .ifmt = 
").append(HexDump.shortToHex(ifmt)).append("\n");
-               buffer.append("[/SXDI]\n");
-               return buffer.toString();
+       @Override
+       public HSSFRecordTypes getGenericRecordType() {
+               return HSSFRecordTypes.DATA_ITEM;
        }
 
        @Override
-       public DataItemRecord copy() {
-               return new DataItemRecord(this);
+       public Map<String, Supplier<?>> getGenericProperties() {
+               return GenericRecordUtil.getGenericProperties(
+                       "isxvdData", () -> isxvdData,
+                       "iiftab", () -> iiftab,
+                       "df", () -> df,
+                       "isxvd", () -> isxvd,
+                       "isxvi", () -> isxvi,
+                       "ifmt", () -> ifmt
+               );
        }
 }

Modified: 
poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/ExtendedPivotTableViewFieldsRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/ExtendedPivotTableViewFieldsRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- 
poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/ExtendedPivotTableViewFieldsRecord.java
 (original)
+++ 
poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/ExtendedPivotTableViewFieldsRecord.java
 Sun Apr 12 22:03:52 2020
@@ -17,9 +17,13 @@
 
 package org.apache.poi.hssf.record.pivottable;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.hssf.record.HSSFRecordTypes;
 import org.apache.poi.hssf.record.RecordInputStream;
 import org.apache.poi.hssf.record.StandardRecord;
-import org.apache.poi.util.HexDump;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.RecordFormatException;
 import org.apache.poi.util.StringUtil;
@@ -119,23 +123,24 @@ public final class ExtendedPivotTableVie
        }
 
        @Override
-       public String toString() {
-               StringBuilder buffer = new StringBuilder();
-
-               buffer.append("[SXVDEX]\n");
+       public ExtendedPivotTableViewFieldsRecord copy() {
+               return new ExtendedPivotTableViewFieldsRecord(this);
+       }
 
-               buffer.append("    .grbit1 
=").append(HexDump.intToHex(_grbit1)).append("\n");
-               buffer.append("    .grbit2 
=").append(HexDump.byteToHex(_grbit2)).append("\n");
-               buffer.append("    .citmShow 
=").append(HexDump.byteToHex(_citmShow)).append("\n");
-               buffer.append("    .isxdiSort 
=").append(HexDump.shortToHex(_isxdiSort)).append("\n");
-               buffer.append("    .isxdiShow 
=").append(HexDump.shortToHex(_isxdiShow)).append("\n");
-               buffer.append("    .subtotalName 
=").append(_subtotalName).append("\n");
-               buffer.append("[/SXVDEX]\n");
-               return buffer.toString();
+       @Override
+       public HSSFRecordTypes getGenericRecordType() {
+               return HSSFRecordTypes.EXTENDED_PIVOT_TABLE_VIEW_FIELDS;
        }
 
        @Override
-       public ExtendedPivotTableViewFieldsRecord copy() {
-               return new ExtendedPivotTableViewFieldsRecord(this);
+       public Map<String, Supplier<?>> getGenericProperties() {
+               return GenericRecordUtil.getGenericProperties(
+                       "grbit1", () -> _grbit1,
+                       "grbit2", () -> _grbit2,
+                       "citmShow", () -> _citmShow,
+                       "isxdiSort", () -> _isxdiSort,
+                       "isxdiShow", () -> _isxdiShow,
+                       "subtotalName", () -> _subtotalName
+               );
        }
 }

Modified: 
poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/PageItemRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/PageItemRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- 
poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/PageItemRecord.java 
(original)
+++ 
poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/PageItemRecord.java 
Sun Apr 12 22:03:52 2020
@@ -17,11 +17,15 @@
 
 package org.apache.poi.hssf.record.pivottable;
 
+import java.util.Map;
+import java.util.function.Supplier;
 import java.util.stream.Stream;
 
+import org.apache.poi.common.usermodel.GenericRecord;
+import org.apache.poi.hssf.record.HSSFRecordTypes;
 import org.apache.poi.hssf.record.RecordInputStream;
 import org.apache.poi.hssf.record.StandardRecord;
-import org.apache.poi.util.HexDump;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.RecordFormatException;
 
@@ -31,7 +35,7 @@ import org.apache.poi.util.RecordFormatE
 public final class PageItemRecord extends StandardRecord {
        public static final short sid = 0x00B6;
 
-       private static final class FieldInfo {
+       private static final class FieldInfo implements GenericRecord {
                public static final int ENCODED_SIZE = 6;
                /** Index to the View Item SXVI(0x00B2) record */
                private int _isxvi;
@@ -52,18 +56,19 @@ public final class PageItemRecord extend
                        _idObj = in.readShort();
                }
 
-               protected void serialize(LittleEndianOutput out) {
+               private void serialize(LittleEndianOutput out) {
                        out.writeShort(_isxvi);
                        out.writeShort(_isxvd);
                        out.writeShort(_idObj);
                }
 
-               public void appendDebugInfo(StringBuilder sb) {
-                       sb.append('(');
-                       sb.append( "isxvi=").append(HexDump.shortToHex(_isxvi));
-                       sb.append(" isxvd=").append(HexDump.shortToHex(_isxvd));
-                       sb.append(" idObj=").append(HexDump.shortToHex(_idObj));
-                       sb.append(')');
+               @Override
+               public Map<String, Supplier<?>> getGenericProperties() {
+                       return GenericRecordUtil.getGenericProperties(
+                               "isxvi", () -> _isxvi,
+                               "isxvd", () -> _isxvd,
+                               "idObj", () -> _idObj
+                       );
                }
        }
 
@@ -107,21 +112,17 @@ public final class PageItemRecord extend
        }
 
        @Override
-       public String toString() {
-               StringBuilder sb = new StringBuilder();
+       public PageItemRecord copy() {
+               return new PageItemRecord(this);
+       }
 
-               sb.append("[SXPI]\n");
-               for (int i = 0; i < _fieldInfos.length; i++) {
-                       sb.append("    item[").append(i).append("]=");
-                       _fieldInfos[i].appendDebugInfo(sb);
-                       sb.append('\n');
-               }
-               sb.append("[/SXPI]\n");
-               return sb.toString();
+       @Override
+       public HSSFRecordTypes getGenericRecordType() {
+               return HSSFRecordTypes.PAGE_ITEM;
        }
 
        @Override
-       public PageItemRecord copy() {
-               return new PageItemRecord(this);
+       public Map<String, Supplier<?>> getGenericProperties() {
+               return GenericRecordUtil.getGenericProperties("fieldInfos", () 
-> _fieldInfos);
        }
 }

Modified: 
poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/StreamIDRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/StreamIDRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- 
poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/StreamIDRecord.java 
(original)
+++ 
poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/StreamIDRecord.java 
Sun Apr 12 22:03:52 2020
@@ -17,9 +17,13 @@
 
 package org.apache.poi.hssf.record.pivottable;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.hssf.record.HSSFRecordTypes;
 import org.apache.poi.hssf.record.RecordInputStream;
 import org.apache.poi.hssf.record.StandardRecord;
-import org.apache.poi.util.HexDump;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 
 /**
@@ -55,18 +59,17 @@ public final class StreamIDRecord extend
        }
 
        @Override
-       public String toString() {
-               StringBuilder buffer = new StringBuilder();
-
-               buffer.append("[SXIDSTM]\n");
-               buffer.append("    .idstm      
=").append(HexDump.shortToHex(idstm)).append('\n');
+       public StreamIDRecord copy() {
+               return new StreamIDRecord(this);
+       }
 
-               buffer.append("[/SXIDSTM]\n");
-               return buffer.toString();
+       @Override
+       public HSSFRecordTypes getGenericRecordType() {
+               return HSSFRecordTypes.STREAM_ID;
        }
 
        @Override
-       public StreamIDRecord copy() {
-               return new StreamIDRecord(this);
+       public Map<String, Supplier<?>> getGenericProperties() {
+               return GenericRecordUtil.getGenericProperties("idstm", () -> 
idstm);
        }
 }

Modified: 
poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/ViewDefinitionRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/ViewDefinitionRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- 
poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/ViewDefinitionRecord.java
 (original)
+++ 
poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/ViewDefinitionRecord.java
 Sun Apr 12 22:03:52 2020
@@ -17,9 +17,14 @@
 
 package org.apache.poi.hssf.record.pivottable;
 
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.hssf.record.HSSFRecordTypes;
 import org.apache.poi.hssf.record.RecordInputStream;
 import org.apache.poi.hssf.record.StandardRecord;
-import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.StringUtil;
 
@@ -153,39 +158,42 @@ public final class ViewDefinitionRecord
        }
 
        @Override
-       public String toString() {
-               StringBuilder buffer = new StringBuilder();
-
-               buffer.append("[SXVIEW]\n");
-               buffer.append("    .rwFirst      
=").append(HexDump.shortToHex(rwFirst)).append('\n');
-               buffer.append("    .rwLast       
=").append(HexDump.shortToHex(rwLast)).append('\n');
-               buffer.append("    .colFirst     
=").append(HexDump.shortToHex(colFirst)).append('\n');
-               buffer.append("    .colLast      
=").append(HexDump.shortToHex(colLast)).append('\n');
-               buffer.append("    .rwFirstHead  
=").append(HexDump.shortToHex(rwFirstHead)).append('\n');
-               buffer.append("    .rwFirstData  
=").append(HexDump.shortToHex(rwFirstData)).append('\n');
-               buffer.append("    .colFirstData 
=").append(HexDump.shortToHex(colFirstData)).append('\n');
-               buffer.append("    .iCache       
=").append(HexDump.shortToHex(iCache)).append('\n');
-               buffer.append("    .reserved     
=").append(HexDump.shortToHex(reserved)).append('\n');
-               buffer.append("    .sxaxis4Data  
=").append(HexDump.shortToHex(sxaxis4Data)).append('\n');
-               buffer.append("    .ipos4Data    
=").append(HexDump.shortToHex(ipos4Data)).append('\n');
-               buffer.append("    .cDim         
=").append(HexDump.shortToHex(cDim)).append('\n');
-               buffer.append("    .cDimRw       
=").append(HexDump.shortToHex(cDimRw)).append('\n');
-               buffer.append("    .cDimCol      
=").append(HexDump.shortToHex(cDimCol)).append('\n');
-               buffer.append("    .cDimPg       
=").append(HexDump.shortToHex(cDimPg)).append('\n');
-               buffer.append("    .cDimData     
=").append(HexDump.shortToHex(cDimData)).append('\n');
-               buffer.append("    .cRw          
=").append(HexDump.shortToHex(cRw)).append('\n');
-               buffer.append("    .cCol         
=").append(HexDump.shortToHex(cCol)).append('\n');
-               buffer.append("    .grbit        
=").append(HexDump.shortToHex(grbit)).append('\n');
-               buffer.append("    .itblAutoFmt  
=").append(HexDump.shortToHex(itblAutoFmt)).append('\n');
-               buffer.append("    .name         =").append(name).append('\n');
-               buffer.append("    .dataField    
=").append(dataField).append('\n');
+       public ViewDefinitionRecord copy() {
+               return new ViewDefinitionRecord(this);
+       }
 
-               buffer.append("[/SXVIEW]\n");
-               return buffer.toString();
+       @Override
+       public HSSFRecordTypes getGenericRecordType() {
+               return HSSFRecordTypes.VIEW_DEFINITION;
        }
 
        @Override
-       public ViewDefinitionRecord copy() {
-               return new ViewDefinitionRecord(this);
+       public Map<String, Supplier<?>> getGenericProperties() {
+               final Map<String,Supplier<?>> m = new LinkedHashMap<>();
+
+               m.put("rwFirst", () -> rwFirst);
+               m.put("rwLast", () -> rwLast);
+               m.put("colFirst", () -> colFirst);
+               m.put("colLast", () -> colLast);
+               m.put("rwFirstHead", () -> rwFirstHead);
+               m.put("rwFirstData", () -> rwFirstData);
+               m.put("colFirstData", () -> colFirstData);
+               m.put("iCache", () -> iCache);
+               m.put("reserved", () -> reserved);
+               m.put("sxaxis4Data", () -> sxaxis4Data);
+               m.put("ipos4Data", () -> ipos4Data);
+               m.put("cDim", () -> cDim);
+               m.put("cDimRw", () -> cDimRw);
+               m.put("cDimCol", () -> cDimCol);
+               m.put("cDimPg", () -> cDimPg);
+               m.put("cDimData", () -> cDimData);
+               m.put("cRw", () -> cRw);
+               m.put("cCol", () -> cCol);
+               m.put("grbit", () -> grbit);
+               m.put("itblAutoFmt", () -> itblAutoFmt);
+               m.put("name", () -> name);
+               m.put("dataField", () -> dataField);
+
+               return Collections.unmodifiableMap(m);
        }
 }

Modified: 
poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/ViewFieldsRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/ViewFieldsRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- 
poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/ViewFieldsRecord.java 
(original)
+++ 
poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/ViewFieldsRecord.java 
Sun Apr 12 22:03:52 2020
@@ -17,9 +17,13 @@
 
 package org.apache.poi.hssf.record.pivottable;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.hssf.record.HSSFRecordTypes;
 import org.apache.poi.hssf.record.RecordInputStream;
 import org.apache.poi.hssf.record.StandardRecord;
-import org.apache.poi.util.HexDump;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.StringUtil;
 
@@ -113,21 +117,23 @@ public final class ViewFieldsRecord exte
        }
 
        @Override
-       public String toString() {
-               StringBuilder buffer = new StringBuilder();
-               buffer.append("[SXVD]\n");
-               buffer.append("    .sxaxis    = 
").append(HexDump.shortToHex(_sxaxis)).append('\n');
-               buffer.append("    .cSub      = 
").append(HexDump.shortToHex(_cSub)).append('\n');
-               buffer.append("    .grbitSub  = 
").append(HexDump.shortToHex(_grbitSub)).append('\n');
-               buffer.append("    .cItm      = 
").append(HexDump.shortToHex(_cItm)).append('\n');
-               buffer.append("    .name      = ").append(_name).append('\n');
+       public ViewFieldsRecord copy() {
+               return new ViewFieldsRecord(this);
+       }
 
-               buffer.append("[/SXVD]\n");
-               return buffer.toString();
+       @Override
+       public HSSFRecordTypes getGenericRecordType() {
+               return HSSFRecordTypes.VIEW_FIELDS;
        }
 
        @Override
-       public ViewFieldsRecord copy() {
-               return new ViewFieldsRecord(this);
+       public Map<String, Supplier<?>> getGenericProperties() {
+               return GenericRecordUtil.getGenericProperties(
+                       "sxaxis", () -> _sxaxis,
+                       "cSub", () -> _cSub,
+                       "grbitSub", () -> _grbitSub,
+                       "cItm", () -> _cItm,
+                       "name", () -> _name
+               );
        }
 }

Modified: 
poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/ViewSourceRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/ViewSourceRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- 
poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/ViewSourceRecord.java 
(original)
+++ 
poi/trunk/src/java/org/apache/poi/hssf/record/pivottable/ViewSourceRecord.java 
Sun Apr 12 22:03:52 2020
@@ -17,9 +17,13 @@
 
 package org.apache.poi.hssf.record.pivottable;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.hssf.record.HSSFRecordTypes;
 import org.apache.poi.hssf.record.RecordInputStream;
 import org.apache.poi.hssf.record.StandardRecord;
-import org.apache.poi.util.HexDump;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 
 /**
@@ -55,18 +59,17 @@ public final class ViewSourceRecord exte
        }
 
        @Override
-       public String toString() {
-               StringBuilder buffer = new StringBuilder();
-
-               buffer.append("[SXVS]\n");
-               buffer.append("    .vs      
=").append(HexDump.shortToHex(vs)).append('\n');
+       public ViewSourceRecord copy() {
+               return new ViewSourceRecord(this);
+       }
 
-               buffer.append("[/SXVS]\n");
-               return buffer.toString();
+       @Override
+       public HSSFRecordTypes getGenericRecordType() {
+               return HSSFRecordTypes.VIEW_SOURCE;
        }
 
        @Override
-       public ViewSourceRecord copy() {
-               return new ViewSourceRecord(this);
+       public Map<String, Supplier<?>> getGenericProperties() {
+               return GenericRecordUtil.getGenericProperties("vs", () -> vs);
        }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFChart.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFChart.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFChart.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFChart.java Sun Apr 12 
22:03:52 2020
@@ -775,9 +775,9 @@ public final class HSSFChart {
         return r;
     }
 
-    private SeriesToChartGroupRecord createSeriesToChartGroupRecord()
+    private SeriesChartGroupIndexRecord createSeriesToChartGroupRecord()
     {
-        return new SeriesToChartGroupRecord();
+        return new SeriesChartGroupIndexRecord();
     }
 
     private DataFormatRecord createDataFormatRecord()

Modified: poi/trunk/src/java/org/apache/poi/poifs/crypt/Decryptor.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/crypt/Decryptor.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/crypt/Decryptor.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/crypt/Decryptor.java Sun Apr 12 
22:03:52 2020
@@ -192,7 +192,7 @@ public abstract class Decryptor implemen
     @Override
     public Map<String, Supplier<?>> getGenericProperties() {
         return GenericRecordUtil.getGenericProperties(
-            "secretKey", secretKey::getEncoded,
+            "secretKey", secretKey == null ? () -> null : 
secretKey::getEncoded,
             "verifier", this::getVerifier,
             "integrityHmacKey", this::getIntegrityHmacKey,
             "integrityHmacValue", this::getIntegrityHmacValue

Modified: poi/trunk/src/java/org/apache/poi/poifs/crypt/Encryptor.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/crypt/Encryptor.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/crypt/Encryptor.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/crypt/Encryptor.java Sun Apr 12 
22:03:52 2020
@@ -102,7 +102,7 @@ public abstract class Encryptor implemen
     @Override
     public Map<String, Supplier<?>> getGenericProperties() {
         return GenericRecordUtil.getGenericProperties(
-            "secretKey", secretKey::getEncoded
+            "secretKey", secretKey == null ? () -> null : secretKey::getEncoded
         );
     }
 }

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/Formula.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/Formula.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/Formula.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/Formula.java Sun Apr 12 
22:03:52 2020
@@ -18,11 +18,15 @@
 package org.apache.poi.ss.formula;
 
 import java.util.Arrays;
+import java.util.Map;
+import java.util.function.Supplier;
 
+import org.apache.poi.common.usermodel.GenericRecord;
 import org.apache.poi.ss.formula.ptg.ExpPtg;
 import org.apache.poi.ss.formula.ptg.Ptg;
 import org.apache.poi.ss.formula.ptg.TblPtg;
 import org.apache.poi.ss.util.CellReference;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.LittleEndianByteArrayInputStream;
@@ -32,7 +36,7 @@ import org.apache.poi.util.LittleEndianO
 /**
  * Encapsulates an encoded formula token array.
  */
-public class Formula {
+public class Formula implements GenericRecord {
 
        //Arbitrarily set.  May need to increase.
        private static final int MAX_ENCODED_LEN = 100000;
@@ -195,4 +199,12 @@ public class Formula {
        public boolean isSame(Formula other) {
                return Arrays.equals(_byteEncoding, other._byteEncoding);
        }
+
+       @Override
+       public Map<String, Supplier<?>> getGenericProperties() {
+               return GenericRecordUtil.getGenericProperties(
+                       "tokens", this::getTokens,
+                       "expReference", this::getExpReference
+               );
+       }
 }

Modified: 
poi/trunk/src/java/org/apache/poi/ss/formula/ptg/AbstractFunctionPtg.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/AbstractFunctionPtg.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/AbstractFunctionPtg.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/AbstractFunctionPtg.java 
Sun Apr 12 22:03:52 2020
@@ -18,9 +18,12 @@
 package org.apache.poi.ss.formula.ptg;
 
 import java.util.Locale;
+import java.util.Map;
+import java.util.function.Supplier;
 
 import org.apache.poi.ss.formula.function.FunctionMetadata;
 import org.apache.poi.ss.formula.function.FunctionMetadataRegistry;
+import org.apache.poi.util.GenericRecordUtil;
 
 /**
  * This class provides the base functionality for Excel sheet functions
@@ -56,10 +59,6 @@ public abstract class AbstractFunctionPt
         return false;
     }
 
-    public final String toString() {
-        return getClass().getName() + " [" + lookupName(_functionIndex) + " 
nArgs=" + _numberOfArgs + "]";
-    }
-
     public final short getFunctionIndex() {
         return _functionIndex;
     }
@@ -168,4 +167,15 @@ public abstract class AbstractFunctionPt
         }
         return paramClass[index];
     }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "functionIndex", this::getFunctionIndex,
+            "functionName", this::getName,
+            "numberOfOperands", this::getNumberOfOperands,
+            "externalFunction", this::isExternalFunction,
+            "defaultOperandClass", this::getDefaultOperandClass
+        );
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Area2DPtgBase.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Area2DPtgBase.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Area2DPtgBase.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Area2DPtgBase.java Sun Apr 
12 22:03:52 2020
@@ -57,13 +57,4 @@ public abstract class Area2DPtgBase exte
        public final String toFormulaString() {
                return formatReferenceAsString();
        }
-
-       public final String toString() {
-               StringBuilder sb = new StringBuilder();
-               sb.append(getClass().getName());
-               sb.append(" [");
-               sb.append(formatReferenceAsString());
-               sb.append("]");
-               return sb.toString();
-       }
 }

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Area3DPtg.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Area3DPtg.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Area3DPtg.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Area3DPtg.java Sun Apr 12 
22:03:52 2020
@@ -17,11 +17,15 @@
 
 package org.apache.poi.ss.formula.ptg;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
 import org.apache.poi.ss.SpreadsheetVersion;
 import org.apache.poi.ss.formula.ExternSheetReferenceToken;
 import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
 import org.apache.poi.ss.formula.WorkbookDependentFormula;
 import org.apache.poi.ss.util.AreaReference;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
 
@@ -67,18 +71,6 @@ public final class Area3DPtg extends Are
        }
 
        @Override
-       public String toString() {
-               StringBuilder sb = new StringBuilder();
-               sb.append(getClass().getName());
-               sb.append(" [");
-               sb.append("sheetIx=").append(getExternSheetIndex());
-               sb.append(" ! ");
-               sb.append(formatReferenceAsString());
-               sb.append("]");
-               return sb.toString();
-       }
-
-       @Override
        public void write(LittleEndianOutput out) {
                out.writeByte(sid + getPtgClass());
                out.writeShort(field_1_index_extern_sheet);
@@ -117,4 +109,12 @@ public final class Area3DPtg extends Are
        public Area3DPtg copy() {
                return new Area3DPtg(this);
        }
+
+       @Override
+       public Map<String, Supplier<?>> getGenericProperties() {
+               return GenericRecordUtil.getGenericProperties(
+                       "base", super::getGenericProperties,
+                       "externSheetIndex", this::getExternSheetIndex
+               );
+       }
 }

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Area3DPxg.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Area3DPxg.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Area3DPxg.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Area3DPxg.java Sun Apr 12 
22:03:52 2020
@@ -17,11 +17,15 @@
 
 package org.apache.poi.ss.formula.ptg;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
 import org.apache.poi.ss.SpreadsheetVersion;
 import org.apache.poi.ss.formula.SheetIdentifier;
 import org.apache.poi.ss.formula.SheetRangeAndWorkbookIndexFormatter;
 import org.apache.poi.ss.formula.SheetRangeIdentifier;
 import org.apache.poi.ss.util.AreaReference;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 
 /**
@@ -65,27 +69,6 @@ public final class Area3DPxg extends Are
         this(-1, sheetName, arearef);
     }
 
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append(getClass().getName());
-        sb.append(" [");
-        if (externalWorkbookNumber >= 0) {
-            sb.append(" [");
-            sb.append("workbook=").append(getExternalWorkbookNumber());
-            sb.append("] ");
-        }
-        sb.append("sheet=").append(getSheetName());
-        if (lastSheetName != null) {
-            sb.append(" : ");
-            sb.append("sheet=").append(lastSheetName);
-        }
-        sb.append(" ! ");
-        sb.append(formatReferenceAsString());
-        sb.append("]");
-        return sb.toString();
-    }
-
     public int getExternalWorkbookNumber() {
         return externalWorkbookNumber;
     }
@@ -127,4 +110,14 @@ public final class Area3DPxg extends Are
     public Area3DPxg copy() {
         return new Area3DPxg(this);
     }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "base", super::getGenericProperties,
+            "externalWorkbookNumber", this::getExternalWorkbookNumber,
+            "sheetName", this::getSheetName,
+            "lastSheetName", this::getLastSheetName
+        );
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/AreaErrPtg.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/AreaErrPtg.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/AreaErrPtg.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/AreaErrPtg.java Sun Apr 12 
22:03:52 2020
@@ -17,7 +17,11 @@
 
 package org.apache.poi.ss.formula.ptg;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
 import org.apache.poi.ss.usermodel.FormulaError;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
 
@@ -63,4 +67,12 @@ public final class AreaErrPtg extends Op
                // immutable
                return this;
        }
+
+       @Override
+       public Map<String, Supplier<?>> getGenericProperties() {
+               return GenericRecordUtil.getGenericProperties(
+                       "unused1", () -> unused1,
+                       "unused2", () -> unused2
+               );
+       }
 }
\ No newline at end of file

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/AreaPtgBase.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/AreaPtgBase.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/AreaPtgBase.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/AreaPtgBase.java Sun Apr 
12 22:03:52 2020
@@ -17,11 +17,15 @@
 
 package org.apache.poi.ss.formula.ptg;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
 import org.apache.poi.ss.SpreadsheetVersion;
 import org.apache.poi.ss.util.AreaReference;
 import org.apache.poi.ss.util.CellReference;
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
 
@@ -296,4 +300,19 @@ public abstract class AreaPtgBase extend
     public byte getDefaultOperandClass() {
         return Ptg.CLASS_REF;
     }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "firstRow", this::getFirstRow,
+            "firstRowRelative", this::isFirstRowRelative,
+            "firstColumn", this::getFirstColumn,
+            "firstColRelative", this::isFirstColRelative,
+            "lastRow", this::getLastRow,
+            "lastRowRelative", this::isLastRowRelative,
+            "lastColumn", this::getLastColumn,
+            "lastColRelative", this::isLastColRelative,
+            "formatReference", this::formatReferenceAsString
+        );
+    }
 }

Copied: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ArrayInitialPtg.java 
(from r1876397, poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ArrayPtg.java)
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ArrayInitialPtg.java?p2=poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ArrayInitialPtg.java&p1=poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ArrayPtg.java&r1=1876397&r2=1876433&rev=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ArrayPtg.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ArrayInitialPtg.java Sun 
Apr 12 22:03:52 2020
@@ -17,271 +17,82 @@
 
 package org.apache.poi.ss.formula.ptg;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
 import org.apache.poi.ss.formula.constant.ConstantValueParser;
-import org.apache.poi.ss.formula.constant.ErrorConstant;
-import org.apache.poi.ss.util.NumberToTextConverter;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
 
 /**
- * ArrayPtg - handles arrays
- *
- * The ArrayPtg is a little weird, the size of the Ptg when parsing initially 
only
- * includes the Ptg sid and the reserved bytes. The next Ptg in the expression 
then follows.
- * It is only after the "size" of all the Ptgs is met, that the ArrayPtg data 
is actually
- * held after this. So Ptg.createParsedExpression keeps track of the number of
- * ArrayPtg elements and need to parse the data upto the FORMULA record size.
+ * Represents the initial plain tArray token (without the constant data that 
trails the whole
+ * formula).  Objects of this class are only temporary and cannot be used as 
{@link Ptg}s.
+ * These temporary objects get converted to {@link ArrayInitialPtg} by the
+ * {@link #finishReading(LittleEndianInput)} method.
  */
-public final class ArrayPtg extends Ptg {
-       public static final byte sid = 0x20;
-
-       private static final int RESERVED_FIELD_LEN = 7;
-       /**
-        * The size of the plain tArray token written within the standard 
formula tokens
-        * (not including the data which comes after all formula tokens)
-        */
-       public static final int PLAIN_TOKEN_SIZE = 1 + RESERVED_FIELD_LEN;
-
-       // 7 bytes of data (stored as an int, short and byte here)
-       private final int _reserved0Int;
-       private final int _reserved1Short;
-       private final int _reserved2Byte;
-
-       // data from these fields comes after the Ptg data of all tokens in 
current formula
-       private final int _nColumns;
-       private final int _nRows;
-       private final Object[] _arrayValues;
-
-       ArrayPtg(int reserved0, int reserved1, int reserved2, int nColumns, int 
nRows, Object[] arrayValues) {
-               _reserved0Int = reserved0;
-               _reserved1Short = reserved1;
-               _reserved2Byte = reserved2;
-               _nColumns = nColumns;
-               _nRows = nRows;
-               _arrayValues = arrayValues.clone();
+final class ArrayInitialPtg extends Ptg {
+       private final int _reserved0;
+       private final int _reserved1;
+       private final int _reserved2;
+
+       public ArrayInitialPtg(LittleEndianInput in) {
+               _reserved0 = in.readInt();
+               _reserved1 = in.readUShort();
+               _reserved2 = in.readUByte();
        }
-
-       public ArrayPtg(ArrayPtg other) {
-               _reserved0Int = other._reserved0Int;
-               _reserved1Short = other._reserved1Short;
-               _reserved2Byte = other._reserved2Byte;
-               _nColumns = other._nColumns;
-               _nRows = other._nRows;
-               _arrayValues = (other._arrayValues == null) ? null : 
other._arrayValues.clone();
+       private static RuntimeException invalid() {
+               throw new IllegalStateException("This object is a partially 
initialised tArray, and cannot be used as a Ptg");
        }
-
-       /**
-        * @param values2d array values arranged in rows
-        */
-       public ArrayPtg(Object[][] values2d) {
-               int nColumns = values2d[0].length;
-               int nRows = values2d.length;
-               // convert 2-d to 1-d array (row by row according to 
getValueIndex())
-               _nColumns = (short) nColumns;
-               _nRows = (short) nRows;
-
-               Object[] vv = new Object[_nColumns * _nRows];
-               for (int r=0; r<nRows; r++) {
-                       Object[] rowData = values2d[r];
-                       for (int c=0; c<nColumns; c++) {
-                               vv[getValueIndex(c, r)] = rowData[c];
-                       }
-               }
-
-               _arrayValues = vv;
-               _reserved0Int = 0;
-               _reserved1Short = 0;
-               _reserved2Byte = 0;
+       public byte getDefaultOperandClass() {
+               throw invalid();
        }
-       /**
-        * @return 2-d array (inner index is rowIx, outer index is colIx)
-        */
-       public Object[][] getTokenArrayValues() {
-               if (_arrayValues == null) {
-                       throw new IllegalStateException("array values not read 
yet");
-               }
-               Object[][] result = new Object[_nRows][_nColumns];
-               for (int r = 0; r < _nRows; r++) {
-                       Object[] rowData = result[r];
-                       for (int c = 0; c < _nColumns; c++) {
-                               rowData[c] = _arrayValues[getValueIndex(c, r)];
-                       }
-               }
-               return result;
+       public int getSize() {
+               return ArrayPtg.PLAIN_TOKEN_SIZE;
        }
-
        public boolean isBaseToken() {
                return false;
        }
-
-       public String toString() {
-               StringBuilder sb = new StringBuilder("[ArrayPtg]\n");
-
-               sb.append("nRows = ").append(getRowCount()).append("\n");
-               sb.append("nCols = ").append(getColumnCount()).append("\n");
-               if (_arrayValues == null) {
-                       sb.append("  #values#uninitialised#\n");
-               } else {
-                       sb.append("  ").append(toFormulaString());
-               }
-               return sb.toString();
-       }
-
-       /**
-        * Note - (2D) array elements are stored row by row
-        * @return the index into the internal 1D array for the specified 
column and row
-        */
-       /* package */ int getValueIndex(int colIx, int rowIx) {
-               if(colIx < 0 || colIx >= _nColumns) {
-                       throw new IllegalArgumentException("Specified colIx (" 
+ colIx
-                                       + ") is outside the allowed range (0.." 
+ (_nColumns-1) + ")");
-               }
-               if(rowIx < 0 || rowIx >= _nRows) {
-                       throw new IllegalArgumentException("Specified rowIx (" 
+ rowIx
-                                       + ") is outside the allowed range (0.." 
+ (_nRows-1) + ")");
-               }
-               return rowIx * _nColumns + colIx;
-       }
-
-       public void write(LittleEndianOutput out) {
-               out.writeByte(sid + getPtgClass());
-               out.writeInt(_reserved0Int);
-               out.writeShort(_reserved1Short);
-               out.writeByte(_reserved2Byte);
-       }
-
-       public int writeTokenValueBytes(LittleEndianOutput out) {
-
-               out.writeByte(_nColumns-1);
-               out.writeShort(_nRows-1);
-               ConstantValueParser.encode(out, _arrayValues);
-               return 3 + ConstantValueParser.getEncodedSize(_arrayValues);
-       }
-
-       public int getRowCount() {
-               return _nRows;
-       }
-
-       public int getColumnCount() {
-               return _nColumns;
-       }
-
-       /** This size includes the size of the array Ptg plus the Array Ptg 
Token value size*/
-       public int getSize() {
-               return PLAIN_TOKEN_SIZE
-                       // data written after the all tokens:
-                       + 1 + 2 // column, row
-                       + ConstantValueParser.getEncodedSize(_arrayValues);
-       }
-
        public String toFormulaString() {
-               StringBuilder b = new StringBuilder();
-               b.append("{");
-               for (int y = 0; y < _nRows; y++) {
-                       if (y > 0) {
-                               b.append(";");
-                       }
-                       for (int x = 0; x < _nColumns; x++) {
-                               if (x > 0) {
-                                       b.append(",");
-                               }
-                               Object o = _arrayValues[getValueIndex(x, y)];
-                               b.append(getConstantText(o));
-                       }
-               }
-               b.append("}");
-               return b.toString();
-       }
-
-       private static String getConstantText(Object o) {
-
-               if (o == null) {
-                       throw new RuntimeException("Array item cannot be null");
-               }
-               if (o instanceof String) {
-                       return "\"" + o + "\"";
-               }
-               if (o instanceof Double) {
-                       return 
NumberToTextConverter.toText(((Double)o).doubleValue());
-               }
-               if (o instanceof Boolean) {
-                       return ((Boolean)o).booleanValue() ? "TRUE" : "FALSE";
-               }
-               if (o instanceof ErrorConstant) {
-                       return ((ErrorConstant)o).getText();
-               }
-               throw new IllegalArgumentException("Unexpected constant class 
(" + o.getClass().getName() + ")");
+               throw invalid();
        }
-
-       public byte getDefaultOperandClass() {
-               return Ptg.CLASS_ARRAY;
+       public void write(LittleEndianOutput out) {
+               throw invalid();
        }
-
        /**
-        * Represents the initial plain tArray token (without the constant data 
that trails the whole
-        * formula).  Objects of this class are only temporary and cannot be 
used as {@link Ptg}s.
-        * These temporary objects get converted to {@link ArrayPtg} by the
-        * {@link #finishReading(LittleEndianInput)} method.
+        * Read in the actual token (array) values. This occurs
+        * AFTER the last Ptg in the expression.
+        * See page 304-305 of 
Excel97-2007BinaryFileFormat(xls)Specification.pdf
         */
-       static final class Initial extends Ptg {
-               private final int _reserved0;
-               private final int _reserved1;
-               private final int _reserved2;
-
-               public Initial(LittleEndianInput in) {
-                       _reserved0 = in.readInt();
-                       _reserved1 = in.readUShort();
-                       _reserved2 = in.readUByte();
-               }
-               private static RuntimeException invalid() {
-                       throw new IllegalStateException("This object is a 
partially initialised tArray, and cannot be used as a Ptg");
-               }
-               public byte getDefaultOperandClass() {
-                       throw invalid();
-               }
-               public int getSize() {
-                       return PLAIN_TOKEN_SIZE;
-               }
-               public boolean isBaseToken() {
-                       return false;
-               }
-               public String toFormulaString() {
-                       throw invalid();
-               }
-               public void write(LittleEndianOutput out) {
-                       throw invalid();
-               }
-               /**
-                * Read in the actual token (array) values. This occurs
-                * AFTER the last Ptg in the expression.
-                * See page 304-305 of 
Excel97-2007BinaryFileFormat(xls)Specification.pdf
-                */
-               public ArrayPtg finishReading(LittleEndianInput in) {
-                       int nColumns = in.readUByte();
-                       short nRows = in.readShort();
-                       //The token_1_columns and token_2_rows do not follow 
the documentation.
-                       //The number of physical rows and columns is actually 
+1 of these values.
-                       //Which is not explicitly documented.
-                       nColumns++;
-                       nRows++;
+       public ArrayPtg finishReading(LittleEndianInput in) {
+               int nColumns = in.readUByte();
+               short nRows = in.readShort();
+               //The token_1_columns and token_2_rows do not follow the 
documentation.
+               //The number of physical rows and columns is actually +1 of 
these values.
+               //Which is not explicitly documented.
+               nColumns++;
+               nRows++;
 
-                       int totalCount = nRows * nColumns;
-                       Object[] arrayValues = ConstantValueParser.parse(in, 
totalCount);
+               int totalCount = nRows * nColumns;
+               Object[] arrayValues = ConstantValueParser.parse(in, 
totalCount);
 
-                       ArrayPtg result = new ArrayPtg(_reserved0, _reserved1, 
_reserved2, nColumns, nRows, arrayValues);
-                       result.setClass(getPtgClass());
-                       return result;
-               }
+               ArrayPtg result = new ArrayPtg(_reserved0, _reserved1, 
_reserved2, nColumns, nRows, arrayValues);
+               result.setClass(getPtgClass());
+               return result;
+       }
 
-               @Override
-               public Initial copy() {
-                       // immutable
-                       return this;
-               }
+       @Override
+       public ArrayInitialPtg copy() {
+               // immutable
+               return this;
        }
 
        @Override
-       public ArrayPtg copy() {
-               return new ArrayPtg(this);
+       public Map<String, Supplier<?>> getGenericProperties() {
+               return GenericRecordUtil.getGenericProperties(
+                       "reserved0", () -> _reserved0,
+                       "reserved1", () -> _reserved1,
+                       "reserved2", () -> _reserved2
+               );
        }
 }

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ArrayPtg.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ArrayPtg.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ArrayPtg.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ArrayPtg.java Sun Apr 12 
22:03:52 2020
@@ -17,10 +17,13 @@
 
 package org.apache.poi.ss.formula.ptg;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
 import org.apache.poi.ss.formula.constant.ConstantValueParser;
 import org.apache.poi.ss.formula.constant.ErrorConstant;
 import org.apache.poi.ss.util.NumberToTextConverter;
-import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 
 /**
@@ -114,19 +117,6 @@ public final class ArrayPtg extends Ptg
                return false;
        }
 
-       public String toString() {
-               StringBuilder sb = new StringBuilder("[ArrayPtg]\n");
-
-               sb.append("nRows = ").append(getRowCount()).append("\n");
-               sb.append("nCols = ").append(getColumnCount()).append("\n");
-               if (_arrayValues == null) {
-                       sb.append("  #values#uninitialised#\n");
-               } else {
-                       sb.append("  ").append(toFormulaString());
-               }
-               return sb.toString();
-       }
-
        /**
         * Note - (2D) array elements are stored row by row
         * @return the index into the internal 1D array for the specified 
column and row
@@ -202,10 +192,10 @@ public final class ArrayPtg extends Ptg
                        return "\"" + o + "\"";
                }
                if (o instanceof Double) {
-                       return 
NumberToTextConverter.toText(((Double)o).doubleValue());
+                       return NumberToTextConverter.toText((Double) o);
                }
                if (o instanceof Boolean) {
-                       return ((Boolean)o).booleanValue() ? "TRUE" : "FALSE";
+                       return (Boolean) o ? "TRUE" : "FALSE";
                }
                if (o instanceof ErrorConstant) {
                        return ((ErrorConstant)o).getText();
@@ -217,71 +207,20 @@ public final class ArrayPtg extends Ptg
                return Ptg.CLASS_ARRAY;
        }
 
-       /**
-        * Represents the initial plain tArray token (without the constant data 
that trails the whole
-        * formula).  Objects of this class are only temporary and cannot be 
used as {@link Ptg}s.
-        * These temporary objects get converted to {@link ArrayPtg} by the
-        * {@link #finishReading(LittleEndianInput)} method.
-        */
-       static final class Initial extends Ptg {
-               private final int _reserved0;
-               private final int _reserved1;
-               private final int _reserved2;
-
-               public Initial(LittleEndianInput in) {
-                       _reserved0 = in.readInt();
-                       _reserved1 = in.readUShort();
-                       _reserved2 = in.readUByte();
-               }
-               private static RuntimeException invalid() {
-                       throw new IllegalStateException("This object is a 
partially initialised tArray, and cannot be used as a Ptg");
-               }
-               public byte getDefaultOperandClass() {
-                       throw invalid();
-               }
-               public int getSize() {
-                       return PLAIN_TOKEN_SIZE;
-               }
-               public boolean isBaseToken() {
-                       return false;
-               }
-               public String toFormulaString() {
-                       throw invalid();
-               }
-               public void write(LittleEndianOutput out) {
-                       throw invalid();
-               }
-               /**
-                * Read in the actual token (array) values. This occurs
-                * AFTER the last Ptg in the expression.
-                * See page 304-305 of 
Excel97-2007BinaryFileFormat(xls)Specification.pdf
-                */
-               public ArrayPtg finishReading(LittleEndianInput in) {
-                       int nColumns = in.readUByte();
-                       short nRows = in.readShort();
-                       //The token_1_columns and token_2_rows do not follow 
the documentation.
-                       //The number of physical rows and columns is actually 
+1 of these values.
-                       //Which is not explicitly documented.
-                       nColumns++;
-                       nRows++;
-
-                       int totalCount = nRows * nColumns;
-                       Object[] arrayValues = ConstantValueParser.parse(in, 
totalCount);
-
-                       ArrayPtg result = new ArrayPtg(_reserved0, _reserved1, 
_reserved2, nColumns, nRows, arrayValues);
-                       result.setClass(getPtgClass());
-                       return result;
-               }
-
-               @Override
-               public Initial copy() {
-                       // immutable
-                       return this;
-               }
-       }
-
        @Override
        public ArrayPtg copy() {
                return new ArrayPtg(this);
        }
+
+       @Override
+       public Map<String, Supplier<?>> getGenericProperties() {
+               return GenericRecordUtil.getGenericProperties(
+                       "reserved0", () -> _reserved0Int,
+                       "reserved1", () -> _reserved1Short,
+                       "reserved2", () -> _reserved2Byte,
+                       "columnCount", this::getColumnCount,
+                       "rowCount", this::getRowCount,
+                       "arrayValues", () -> _arrayValues == null ? 
"#values#uninitialised#" : toFormulaString()
+               );
+       }
 }

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/AttrPtg.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/AttrPtg.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/AttrPtg.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/AttrPtg.java Sun Apr 12 
22:03:52 2020
@@ -17,8 +17,15 @@
 
 package org.apache.poi.ss.formula.ptg;
 
+import static org.apache.poi.util.GenericRecordUtil.getBitsAsString;
+import static org.apache.poi.util.GenericRecordUtil.getEnumBitsAsString;
+
+import java.util.Map;
+import java.util.function.Supplier;
+
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
@@ -166,41 +173,14 @@ public final class AttrPtg extends Contr
         return _chooseFuncOffset;
     }
 
-    public String toString() {
-        StringBuilder sb = new StringBuilder(64);
-        sb.append(getClass().getName()).append(" [");
-
-        if(isSemiVolatile()) {
-            sb.append("volatile ");
-        }
-        if(isSpace()) {
-            sb.append("space count=").append((_data >> 8) & 0x00FF);
-            sb.append(" type=").append(_data & 0x00FF).append(" ");
-        }
-        // the rest seem to be mutually exclusive
-        if(isOptimizedIf()) {
-            sb.append("if dist=").append(_data);
-        } else if(isOptimizedChoose()) {
-            sb.append("choose nCases=").append(_data);
-        } else if(isSkip()) {
-            sb.append("skip dist=").append(_data);
-        } else if(isSum()) {
-            sb.append("sum ");
-        } else if(isBaxcel()) {
-            sb.append("assign ");
-        }
-        sb.append("]");
-        return sb.toString();
-    }
-
     public void write(LittleEndianOutput out) {
         out.writeByte(sid + getPtgClass());
         out.writeByte(_options);
         out.writeShort(_data);
         int[] jt = _jumpTable;
         if (jt != null) {
-            for (int i = 0; i < jt.length; i++) {
-                out.writeShort(jt[i]);
+            for (int value : jt) {
+                out.writeShort(value);
             }
             out.writeShort(_chooseFuncOffset);
         }
@@ -234,34 +214,48 @@ public final class AttrPtg extends Contr
         return -1;
     }
 
-   public String toFormulaString() {
-      if(semiVolatile.isSet(_options)) {
-        return "ATTR(semiVolatile)";
-      }
-      if(optiIf.isSet(_options)) {
-        return "IF";
-      }
-      if( optiChoose.isSet(_options)) {
-        return "CHOOSE";
-      }
-      if(optiSkip.isSet(_options)) {
-        return "";
-      }
-      if(optiSum.isSet(_options)) {
-        return "SUM";
-      }
-      if(baxcel.isSet(_options)) {
-        return "ATTR(baxcel)";
-      }
-      if(space.isSet(_options)) {
-        return "";
-      }
-      return "UNKNOWN ATTRIBUTE";
-     }
+    public String toFormulaString() {
+        if (semiVolatile.isSet(_options)) {
+            return "ATTR(semiVolatile)";
+        }
+        if (optiIf.isSet(_options)) {
+            return "IF";
+        }
+        if (optiChoose.isSet(_options)) {
+            return "CHOOSE";
+        }
+        if (optiSkip.isSet(_options)) {
+            return "";
+        }
+        if (optiSum.isSet(_options)) {
+            return "SUM";
+        }
+        if (baxcel.isSet(_options)) {
+            return "ATTR(baxcel)";
+        }
+        if (space.isSet(_options)) {
+            return "";
+        }
+        return "UNKNOWN ATTRIBUTE";
+    }
 
     @Override
     public AttrPtg copy() {
         // immutable
         return this;
     }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "volatile", this::isSemiVolatile,
+            "options", getBitsAsString(() -> _options,
+                new BitField[]{semiVolatile, optiIf, optiChoose, optiSkip, 
optiSum, baxcel, space},
+                new String[]{"SEMI_VOLATILE", "OPTI_IF", "OPTI_CHOOSE", 
"OPTI_SKIP", "OPTI_SUM", "BAXCEL", "SPACE"}),
+            "space_count", () -> (_data >> 8) & 0xFF,
+            "space_type",  getEnumBitsAsString(() -> _data & 0xFF,
+                new 
int[]{SpaceType.SPACE_BEFORE,SpaceType.CR_BEFORE,SpaceType.SPACE_BEFORE_OPEN_PAREN,SpaceType.CR_BEFORE_OPEN_PAREN,SpaceType.SPACE_BEFORE_CLOSE_PAREN,SpaceType.CR_BEFORE_CLOSE_PAREN,SpaceType.SPACE_AFTER_EQUALITY},
+                new 
String[]{"SPACE_BEFORE","CR_BEFORE","SPACE_BEFORE_OPEN_PAREN","CR_BEFORE_OPEN_PAREN","SPACE_BEFORE_CLOSE_PAREN","CR_BEFORE_CLOSE_PAREN","SPACE_AFTER_EQUALITY"})
+        );
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/BoolPtg.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/BoolPtg.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/BoolPtg.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/BoolPtg.java Sun Apr 12 
22:03:52 2020
@@ -17,6 +17,10 @@
 
 package org.apache.poi.ss.formula.ptg;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
 
@@ -64,4 +68,9 @@ public final class BoolPtg extends Scala
        public BoolPtg copy() {
                return this;
        }
+
+       @Override
+       public Map<String, Supplier<?>> getGenericProperties() {
+               return GenericRecordUtil.getGenericProperties("value", 
this::getValue);
+       }
 }

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Deleted3DPxg.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Deleted3DPxg.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Deleted3DPxg.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Deleted3DPxg.java Sun Apr 
12 22:03:52 2020
@@ -17,8 +17,12 @@
 
 package org.apache.poi.ss.formula.ptg;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
 import org.apache.poi.ss.formula.SheetNameFormatter;
 import org.apache.poi.ss.usermodel.FormulaError;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 
 
@@ -44,22 +48,6 @@ public final class Deleted3DPxg extends
         this(-1, sheetName);
     }
 
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append(getClass().getName());
-        sb.append(" [");
-        if (externalWorkbookNumber >= 0) {
-            sb.append(" [");
-            sb.append("workbook=").append(getExternalWorkbookNumber());
-            sb.append("] ");
-        }
-        sb.append("sheet=").append(getSheetName());
-        sb.append(" ! ");
-        sb.append(FormulaError.REF.getString());
-        sb.append("]");
-        return sb.toString();
-    }
-
     public int getExternalWorkbookNumber() {
         return externalWorkbookNumber;
     }
@@ -101,4 +89,14 @@ public final class Deleted3DPxg extends
     public Deleted3DPxg copy() {
         return new Deleted3DPxg(this);
     }
+
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "externalWorkbookNumber", this::getExternalWorkbookNumber,
+            "sheetName", this::getSheetName,
+            "formulaError", () -> FormulaError.REF
+        );
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/DeletedArea3DPtg.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/DeletedArea3DPtg.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/DeletedArea3DPtg.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/DeletedArea3DPtg.java Sun 
Apr 12 22:03:52 2020
@@ -17,9 +17,13 @@
 
 package org.apache.poi.ss.formula.ptg;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
 import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
 import org.apache.poi.ss.formula.WorkbookDependentFormula;
 import org.apache.poi.ss.usermodel.FormulaError;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
 
@@ -58,6 +62,11 @@ public final class DeletedArea3DPtg exte
        public int getSize() {
                return 11;
        }
+
+       public int getExternSheetIndex() {
+               return field_1_index_extern_sheet;
+       }
+
        public void write(LittleEndianOutput out) {
                out.writeByte(sid + getPtgClass());
                out.writeShort(field_1_index_extern_sheet);
@@ -70,4 +79,13 @@ public final class DeletedArea3DPtg exte
                // immutable
                return this;
        }
+
+       @Override
+       public Map<String, Supplier<?>> getGenericProperties() {
+               return GenericRecordUtil.getGenericProperties(
+                       "externSheetIndex", this::getExternSheetIndex,
+                       "unused1", () -> unused1,
+                       "unused2", () -> unused2
+               );
+       }
 }

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/DeletedRef3DPtg.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/DeletedRef3DPtg.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/DeletedRef3DPtg.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/DeletedRef3DPtg.java Sun 
Apr 12 22:03:52 2020
@@ -18,9 +18,13 @@
 package org.apache.poi.ss.formula.ptg;
 
 
+import java.util.Map;
+import java.util.function.Supplier;
+
 import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
 import org.apache.poi.ss.formula.WorkbookDependentFormula;
 import org.apache.poi.ss.usermodel.FormulaError;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
 
@@ -69,4 +73,12 @@ public final class DeletedRef3DPtg exten
                // immutable
                return this;
        }
+
+       @Override
+       public Map<String, Supplier<?>> getGenericProperties() {
+               return GenericRecordUtil.getGenericProperties(
+                       "externSheetIndex", () -> field_1_index_extern_sheet,
+                       "unused1", () -> unused1
+               );
+       }
 }

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ErrPtg.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ErrPtg.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ErrPtg.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ErrPtg.java Sun Apr 12 
22:03:52 2020
@@ -17,7 +17,11 @@
 
 package org.apache.poi.ss.formula.ptg;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
 import org.apache.poi.ss.usermodel.FormulaError;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
 
@@ -91,4 +95,9 @@ public final class ErrPtg extends Scalar
     public ErrPtg copy() {
         return this;
     }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties("errorCode", 
this::getErrorCode);
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ExpPtg.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ExpPtg.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ExpPtg.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ExpPtg.java Sun Apr 12 
22:03:52 2020
@@ -17,6 +17,10 @@
 
 package org.apache.poi.ss.formula.ptg;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
 
@@ -63,12 +67,15 @@ public final class ExpPtg extends Contro
     }
 
     @Override
-    public String toString() {
-        return "[Array Formula or Shared Formula]\n" + "row = " + getRow() + 
"\n" + "col = " + getColumn() + "\n";
+    public ExpPtg copy() {
+        return this;
     }
 
     @Override
-    public ExpPtg copy() {
-        return this;
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "row", this::getRow,
+            "column", this::getColumn
+        );
     }
 }

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/FuncVarPtg.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/FuncVarPtg.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/FuncVarPtg.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/FuncVarPtg.java Sun Apr 12 
22:03:52 2020
@@ -16,10 +16,14 @@
 ==================================================================== */
 
 package org.apache.poi.ss.formula.ptg;
+import java.util.Map;
+import java.util.function.Supplier;
+
 import org.apache.poi.ss.formula.function.FunctionMetadata;
 import org.apache.poi.ss.formula.function.FunctionMetadataRegistry;
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
 
@@ -93,4 +97,12 @@ public final class FuncVarPtg extends Ab
         // immutable
         return this;
     }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "base", super::getGenericProperties,
+            "cetab", () -> _isCetab
+        );
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/IntPtg.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/IntPtg.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/IntPtg.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/IntPtg.java Sun Apr 12 
22:03:52 2020
@@ -17,6 +17,10 @@
 
 package org.apache.poi.ss.formula.ptg;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
 
@@ -74,4 +78,9 @@ public final class IntPtg extends Scalar
        public IntPtg copy() {
                return this;
        }
+
+       @Override
+       public Map<String, Supplier<?>> getGenericProperties() {
+               return GenericRecordUtil.getGenericProperties("value", 
this::getValue);
+       }
 }

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/MemAreaPtg.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/MemAreaPtg.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/MemAreaPtg.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/MemAreaPtg.java Sun Apr 12 
22:03:52 2020
@@ -17,6 +17,10 @@
 
 package org.apache.poi.ss.formula.ptg;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
 
@@ -61,17 +65,13 @@ public final class MemAreaPtg extends Op
        }
 
        @Override
-       public final String toString() {
-               StringBuilder sb = new StringBuilder(64);
-               sb.append(getClass().getName()).append(" [len=");
-               sb.append(field_2_subex_len);
-               sb.append("]");
-               return sb.toString();
-       }
-
-       @Override
        public MemAreaPtg copy() {
                // immutable
                return this;
        }
+
+       @Override
+       public Map<String, Supplier<?>> getGenericProperties() {
+               return 
GenericRecordUtil.getGenericProperties("lenRefSubexpression", 
this::getLenRefSubexpression);
+       }
 }

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/MemErrPtg.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/MemErrPtg.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/MemErrPtg.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/MemErrPtg.java Sun Apr 12 
22:03:52 2020
@@ -17,6 +17,10 @@
 
 package org.apache.poi.ss.formula.ptg;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
 
@@ -55,8 +59,17 @@ public final class MemErrPtg extends Ope
                return Ptg.CLASS_VALUE;
        }
 
+       public int getLenRefSubexpression() {
+               return field_2_subex_len;
+       }
+
        @Override
        public MemErrPtg copy() {
                return new MemErrPtg(this);
        }
+
+       @Override
+       public Map<String, Supplier<?>> getGenericProperties() {
+               return 
GenericRecordUtil.getGenericProperties("lenRefSubexpression", 
this::getLenRefSubexpression);
+       }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to