diff --git a/iabgpp-encoder/pom.xml b/iabgpp-encoder/pom.xml
index d3ddc08f..e1a96cd4 100644
--- a/iabgpp-encoder/pom.xml
+++ b/iabgpp-encoder/pom.xml
@@ -7,7 +7,7 @@
     <parent>
         <groupId>com.iabgpp</groupId>
         <artifactId>iabgpp-core</artifactId>
-        <version>3.0.8-SNAPSHOT</version>
+        <version>3.0.11-SNAPSHOT</version>
     </parent>
 
     <artifactId>iabgpp-encoder</artifactId>
diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/GppModel.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/GppModel.java
index 12ae0c49..2e4d27c8 100644
--- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/GppModel.java
+++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/GppModel.java
@@ -7,6 +7,7 @@
 import java.util.stream.Collectors;
 import com.iab.gpp.encoder.error.DecodingException;
 import com.iab.gpp.encoder.error.EncodingException;
+import com.iab.gpp.encoder.error.InvalidFieldException;
 import com.iab.gpp.encoder.section.EncodableSection;
 import com.iab.gpp.encoder.section.HeaderV1;
 import com.iab.gpp.encoder.section.Sections;
@@ -33,11 +34,11 @@ public GppModel(String encodedString) throws DecodingException {
     }
   }
 
-  public void setFieldValue(int sectionId, String fieldName, Object value) {
+  public void setFieldValue(int sectionId, String fieldName, Object value) throws InvalidFieldException {
     setFieldValue(Sections.SECTION_ID_NAME_MAP.get(sectionId), fieldName, value);
   }
 
-  public void setFieldValue(String sectionName, String fieldName, Object value) {
+  public void setFieldValue(String sectionName, String fieldName, Object value) throws InvalidFieldException {
     EncodableSection section = null;
     if (!this.sections.containsKey(sectionName)) {
       if (sectionName.equals(TcfCaV1.NAME)) {
@@ -75,7 +76,7 @@ public void setFieldValue(String sectionName, String fieldName, Object value) {
     if (section != null) {
       section.setFieldValue(fieldName, value);
     } else {
-      throw new Error(sectionName + " not found");
+      throw new InvalidFieldException(sectionName + "." + fieldName + " not found");
     }
   }
 
@@ -113,7 +114,11 @@ public boolean hasSection(String sectionName) {
 
   public HeaderV1 getHeader() {
     HeaderV1 header = new HeaderV1();
-    header.setFieldValue("SectionIds", this.getSectionIds());
+    try {
+      header.setFieldValue("SectionIds", this.getSectionIds());
+    } catch (InvalidFieldException e) {
+
+    }
     return header;
   }
 
@@ -204,7 +209,11 @@ public String encode() throws EncodingException {
     }
 
     HeaderV1 header = new HeaderV1();
-    header.setFieldValue("SectionIds", this.getSectionIds());
+    try {
+      header.setFieldValue("SectionIds", this.getSectionIds());
+    } catch (InvalidFieldException e) {
+      throw new EncodingException(e);
+    }
     encodedSections.add(0, header.encode());
 
     String encodedString = encodedSections.stream().collect(Collectors.joining("~"));
diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/AbstractEncodableBitStringDataType.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/AbstractEncodableBitStringDataType.java
index d8c3dcfc..27359760 100644
--- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/AbstractEncodableBitStringDataType.java
+++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/AbstractEncodableBitStringDataType.java
@@ -6,14 +6,10 @@
 public abstract class AbstractEncodableBitStringDataType<T> {
   protected T value;
 
-  public AbstractEncodableBitStringDataType() {
+  protected AbstractEncodableBitStringDataType() {
 
   }
 
-  public AbstractEncodableBitStringDataType(T value) {
-    this.value = value;
-  }
-
   public boolean hasValue() {
     return this.value != null;
   }
diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableBoolean.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableBoolean.java
index bdb29bb1..09d47ac7 100644
--- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableBoolean.java
+++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableBoolean.java
@@ -6,12 +6,13 @@
 
 public class EncodableBoolean extends AbstractEncodableBitStringDataType<Boolean> {
 
-  public EncodableBoolean() {
+  protected EncodableBoolean() {
     super();
   }
 
   public EncodableBoolean(Boolean value) {
-    super(value);
+    super();
+    setValue(value);
   }
 
   public String encode() throws EncodingException {
diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableDatetime.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableDatetime.java
index ad42a95a..f146d0aa 100644
--- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableDatetime.java
+++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableDatetime.java
@@ -6,12 +6,13 @@
 
 public class EncodableDatetime extends AbstractEncodableBitStringDataType<ZonedDateTime> {
 
-  public EncodableDatetime() {
+  protected EncodableDatetime() {
     super();
   }
 
   public EncodableDatetime(ZonedDateTime value) {
-    super(value);
+    super();
+    setValue(value);
   }
 
   public String encode() {
diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFibonacciInteger.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFibonacciInteger.java
index b9d9187e..5d4e1783 100644
--- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFibonacciInteger.java
+++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFibonacciInteger.java
@@ -5,12 +5,13 @@
 
 public class EncodableFibonacciInteger extends AbstractEncodableBitStringDataType<Integer> {
 
-  public EncodableFibonacciInteger() {
+  protected EncodableFibonacciInteger() {
     super();
   }
 
   public EncodableFibonacciInteger(Integer value) {
-    super(value);
+    super();
+    setValue(value);
   }
 
   public String encode() {
diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFibonacciIntegerRange.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFibonacciIntegerRange.java
index e0ec7c64..eaff0382 100644
--- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFibonacciIntegerRange.java
+++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFibonacciIntegerRange.java
@@ -1,18 +1,21 @@
 package com.iab.gpp.encoder.datatype;
 
+import java.util.ArrayList;
 import java.util.List;
+import java.util.TreeSet;
 import com.iab.gpp.encoder.datatype.encoder.FibonacciIntegerRangeEncoder;
 import com.iab.gpp.encoder.datatype.encoder.FixedIntegerEncoder;
 import com.iab.gpp.encoder.error.DecodingException;
 
 public class EncodableFibonacciIntegerRange extends AbstractEncodableBitStringDataType<List<Integer>> {
 
-  public EncodableFibonacciIntegerRange() {
+  protected EncodableFibonacciIntegerRange() {
     super();
   }
 
   public EncodableFibonacciIntegerRange(List<Integer> value) {
-    super(value);
+    super();
+    setValue(value);
   }
 
   public String encode() {
@@ -36,4 +39,15 @@ public String substring(String bitString, int fromIndex) throws DecodingExceptio
     }
     return bitString.substring(fromIndex, index);
   }
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public void setValue(Object value) {
+    super.setValue(new ArrayList<>(new TreeSet<>((List<Integer>) value)));
+  }
+
+  @Override
+  public List<Integer> getValue() {
+    return new ArrayList<>(super.getValue());
+  }
 }
diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedBitfield.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedBitfield.java
index 581d5ff1..e0ae9b8e 100644
--- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedBitfield.java
+++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedBitfield.java
@@ -1,5 +1,6 @@
 package com.iab.gpp.encoder.datatype;
 
+import java.util.ArrayList;
 import java.util.List;
 import com.iab.gpp.encoder.datatype.encoder.FixedBitfieldEncoder;
 import com.iab.gpp.encoder.error.DecodingException;
@@ -7,20 +8,21 @@
 
 public class EncodableFixedBitfield extends AbstractEncodableBitStringDataType<List<Boolean>> {
 
-  private int bitStringLength;
+  private int numElements;
 
-  public EncodableFixedBitfield(int bitStringLength) {
+  protected EncodableFixedBitfield(int numElements) {
     super();
-    this.bitStringLength = bitStringLength;
+    this.numElements = numElements;
   }
 
-  public EncodableFixedBitfield(int bitStringLength, List<Boolean> value) {
-    super(value);
-    this.bitStringLength = bitStringLength;
+  public EncodableFixedBitfield(List<Boolean> value) {
+    super();
+    this.numElements = value.size();
+    setValue(value);
   }
 
   public String encode() throws EncodingException {
-    return FixedBitfieldEncoder.encode(this.value, this.bitStringLength);
+    return FixedBitfieldEncoder.encode(this.value, this.numElements);
   }
 
   public void decode(String bitString) throws DecodingException {
@@ -29,6 +31,24 @@ public void decode(String bitString) throws DecodingException {
 
   public String substring(String bitString, int fromIndex) {
     // TODO: validate
-    return bitString.substring(fromIndex, fromIndex + this.bitStringLength);
+    return bitString.substring(fromIndex, fromIndex + this.numElements);
+  }
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public void setValue(Object value) {
+    List<Boolean> v = new ArrayList<>((List<Boolean>) value);
+    for (int i = v.size(); i < numElements; i++) {
+      v.add(false);
+    }
+    if (v.size() > numElements) {
+      v = v.subList(0, numElements);
+    }
+    super.setValue(v);
+  }
+
+  @Override
+  public List<Boolean> getValue() {
+    return new ArrayList<>(super.getValue());
   }
 }
diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedInteger.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedInteger.java
index 90340f29..8b0fcb7e 100644
--- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedInteger.java
+++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedInteger.java
@@ -7,14 +7,15 @@ public class EncodableFixedInteger extends AbstractEncodableBitStringDataType<In
 
   private int bitStringLength;
 
-  public EncodableFixedInteger(int bitStringLength) {
+  protected EncodableFixedInteger(int bitStringLength) {
     super();
     this.bitStringLength = bitStringLength;
   }
 
   public EncodableFixedInteger(int bitStringLength, Integer value) {
-    super(value);
+    super();
     this.bitStringLength = bitStringLength;
+    setValue(value);
   }
 
   public String encode() {
diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerList.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerList.java
index 99c2d089..ccaca886 100644
--- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerList.java
+++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerList.java
@@ -1,5 +1,6 @@
 package com.iab.gpp.encoder.datatype;
 
+import java.util.ArrayList;
 import java.util.List;
 import com.iab.gpp.encoder.datatype.encoder.FixedIntegerListEncoder;
 import com.iab.gpp.encoder.error.DecodingException;
@@ -10,16 +11,17 @@ public class EncodableFixedIntegerList extends AbstractEncodableBitStringDataTyp
   private int elementBitStringLength;
   private int numElements;
 
-  public EncodableFixedIntegerList(int elementBitStringLength, int size) {
+  protected EncodableFixedIntegerList(int elementBitStringLength, int numElements) {
     super();
     this.elementBitStringLength = elementBitStringLength;
-    this.numElements = size;
+    this.numElements = numElements;
   }
 
   public EncodableFixedIntegerList(int elementBitStringLength, List<Integer> value) {
-    super(value);
+    super();
     this.elementBitStringLength = elementBitStringLength;
     this.numElements = value.size();
+    setValue(value);
   }
 
   public String encode() throws EncodingException {
@@ -34,4 +36,22 @@ public String substring(String bitString, int fromIndex) {
     // TODO: validate
     return bitString.substring(fromIndex, fromIndex + (this.elementBitStringLength * numElements));
   }
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public void setValue(Object value) {
+    List<Integer> v = new ArrayList<>((List<Integer>) value);
+    for (int i = v.size(); i < numElements; i++) {
+      v.add(0);
+    }
+    if (v.size() > numElements) {
+      v = v.subList(0, numElements);
+    }
+    super.setValue(v);
+  }
+
+  @Override
+  public List<Integer> getValue() {
+    return new ArrayList<>(super.getValue());
+  }
 }
diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerRange.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerRange.java
index 84409d9c..e43751af 100644
--- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerRange.java
+++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerRange.java
@@ -1,18 +1,21 @@
 package com.iab.gpp.encoder.datatype;
 
+import java.util.ArrayList;
 import java.util.List;
+import java.util.TreeSet;
 import com.iab.gpp.encoder.datatype.encoder.FixedIntegerEncoder;
 import com.iab.gpp.encoder.datatype.encoder.FixedIntegerRangeEncoder;
 import com.iab.gpp.encoder.error.DecodingException;
 
 public class EncodableFixedIntegerRange extends AbstractEncodableBitStringDataType<List<Integer>> {
 
-  public EncodableFixedIntegerRange() {
+  protected EncodableFixedIntegerRange() {
     super();
   }
 
   public EncodableFixedIntegerRange(List<Integer> value) {
-    super(value);
+    super();
+    setValue(value);
   }
 
   public String encode() {
@@ -37,4 +40,14 @@ public String substring(String bitString, int fromIndex) throws DecodingExceptio
     return bitString.substring(fromIndex, index);
   }
 
+  @SuppressWarnings("unchecked")
+  @Override
+  public void setValue(Object value) {
+    super.setValue(new ArrayList<>(new TreeSet<>((List<Integer>) value)));
+  }
+
+  @Override
+  public List<Integer> getValue() {
+    return new ArrayList<>(super.getValue());
+  }
 }
diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedNullableBitfield.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedNullableBitfield.java
deleted file mode 100644
index 12a8fc1c..00000000
--- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedNullableBitfield.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.iab.gpp.encoder.datatype;
-
-import java.util.List;
-import com.iab.gpp.encoder.datatype.encoder.FixedBitfieldEncoder;
-import com.iab.gpp.encoder.error.DecodingException;
-import com.iab.gpp.encoder.error.EncodingException;
-
-public class EncodableFixedNullableBitfield extends AbstractEncodableBitStringDataType<List<Boolean>> {
-
-  private int bitStringLength;
-
-  public EncodableFixedNullableBitfield(int bitStringLength) {
-    super();
-    this.bitStringLength = bitStringLength;
-  }
-
-  public EncodableFixedNullableBitfield(int bitStringLength, List<Boolean> value) {
-    super(value);
-    this.bitStringLength = bitStringLength;
-  }
-
-  public String encode() throws EncodingException {
-    return FixedBitfieldEncoder.encode(this.value, this.bitStringLength);
-  }
-
-  public void decode(String bitString) throws DecodingException {
-    this.value = FixedBitfieldEncoder.decode(bitString);
-  }
-
-  public String substring(String bitString, int fromIndex) {
-    // TODO: validate
-    return bitString.substring(fromIndex, fromIndex + this.bitStringLength);
-  }
-}
diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedString.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedString.java
index 8ae8035b..ed736fc2 100644
--- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedString.java
+++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedString.java
@@ -8,14 +8,15 @@ public class EncodableFixedString extends AbstractEncodableBitStringDataType<Str
 
   private int stringLength;
 
-  public EncodableFixedString(int stringLength) {
+  protected EncodableFixedString(int stringLength) {
     super();
     this.stringLength = stringLength;
   }
 
   public EncodableFixedString(int stringLength, String value) {
-    super(value);
+    super();
     this.stringLength = stringLength;
+    setValue(value);
   }
 
   public String encode() throws EncodingException {
diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFlexibleBitfield.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFlexibleBitfield.java
index e61deca4..93c3c26b 100644
--- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFlexibleBitfield.java
+++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFlexibleBitfield.java
@@ -1,5 +1,6 @@
 package com.iab.gpp.encoder.datatype;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.function.IntSupplier;
 import com.iab.gpp.encoder.datatype.encoder.FixedBitfieldEncoder;
@@ -10,14 +11,15 @@ public class EncodableFlexibleBitfield extends AbstractEncodableBitStringDataTyp
 
   private IntSupplier getLengthSupplier;
 
-  public EncodableFlexibleBitfield(IntSupplier getLengthSupplier) {
+  protected EncodableFlexibleBitfield(IntSupplier getLengthSupplier) {
     super();
     this.getLengthSupplier = getLengthSupplier;
   }
 
   public EncodableFlexibleBitfield(IntSupplier getLengthSupplier, List<Boolean> value) {
-    super(value);
+    super();
     this.getLengthSupplier = getLengthSupplier;
+    this.setValue(value);
   }
 
   public String encode() throws EncodingException {
@@ -32,4 +34,23 @@ public String substring(String bitString, int fromIndex) {
     // TODO: validate
     return bitString.substring(fromIndex, fromIndex + this.getLengthSupplier.getAsInt());
   }
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public void setValue(Object value) {
+    int numElements = this.getLengthSupplier.getAsInt();
+    List<Boolean> v = new ArrayList<>((List<Boolean>) value);
+    for (int i = v.size(); i < numElements; i++) {
+      v.add(false);
+    }
+    if (v.size() > numElements) {
+      v = v.subList(0, numElements);
+    }
+    super.setValue(v);
+  }
+
+  @Override
+  public List<Boolean> getValue() {
+    return new ArrayList<>(super.getValue());
+  }
 }
diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFibonacciRange.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFibonacciRange.java
index 37630a8b..d32dcc49 100644
--- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFibonacciRange.java
+++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFibonacciRange.java
@@ -2,6 +2,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.TreeSet;
 import com.iab.gpp.encoder.datatype.encoder.FibonacciIntegerRangeEncoder;
 import com.iab.gpp.encoder.datatype.encoder.FixedBitfieldEncoder;
 import com.iab.gpp.encoder.datatype.encoder.FixedIntegerEncoder;
@@ -10,12 +11,13 @@
 
 public class EncodableOptimizedFibonacciRange extends AbstractEncodableBitStringDataType<List<Integer>> {
 
-  public EncodableOptimizedFibonacciRange() {
+  protected EncodableOptimizedFibonacciRange() {
     super();
   }
 
   public EncodableOptimizedFibonacciRange(List<Integer> value) {
-    super(value);
+    super();
+    setValue(value);
   }
 
   public String encode() throws EncodingException {
@@ -61,10 +63,21 @@ public void decode(String bitString) throws DecodingException {
   public String substring(String bitString, int fromIndex) throws DecodingException {
     int max = FixedIntegerEncoder.decode(bitString.substring(fromIndex, fromIndex + 16));
     if (bitString.charAt(fromIndex + 16) == '1') {
-      return (bitString.substring(fromIndex, 17)
+      return (bitString.substring(fromIndex, fromIndex + 17)
           + new EncodableFibonacciIntegerRange().substring(bitString, fromIndex + 17));
     } else {
       return bitString.substring(fromIndex, fromIndex + 17 + max);
     }
   }
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public void setValue(Object value) {
+    super.setValue(new ArrayList<>(new TreeSet<>((List<Integer>) value)));
+  }
+
+  @Override
+  public List<Integer> getValue() {
+    return new ArrayList<>(super.getValue());
+  }
 }
diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFixedRange.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFixedRange.java
index a08428c6..d3250f07 100644
--- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFixedRange.java
+++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFixedRange.java
@@ -2,6 +2,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.TreeSet;
 import com.iab.gpp.encoder.datatype.encoder.FixedBitfieldEncoder;
 import com.iab.gpp.encoder.datatype.encoder.FixedIntegerEncoder;
 import com.iab.gpp.encoder.datatype.encoder.FixedIntegerRangeEncoder;
@@ -10,12 +11,13 @@
 
 public class EncodableOptimizedFixedRange extends AbstractEncodableBitStringDataType<List<Integer>> {
 
-  public EncodableOptimizedFixedRange() {
+  protected EncodableOptimizedFixedRange() {
     super();
   }
 
   public EncodableOptimizedFixedRange(List<Integer> value) {
-    super(value);
+    super();
+    setValue(value);
   }
 
   public String encode() throws EncodingException {
@@ -62,9 +64,21 @@ public void decode(String bitString) throws DecodingException {
   public String substring(String bitString, int fromIndex) throws DecodingException {
     int max = FixedIntegerEncoder.decode(bitString.substring(fromIndex, fromIndex + 16));
     if (bitString.charAt(fromIndex + 16) == '1') {
-      return bitString.substring(fromIndex, 17) + new EncodableFixedIntegerRange().substring(bitString, fromIndex + 17);
+      return bitString.substring(fromIndex, fromIndex + 17)
+          + new EncodableFixedIntegerRange().substring(bitString, fromIndex + 17);
     } else {
       return bitString.substring(fromIndex, fromIndex + 17 + max);
     }
   }
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public void setValue(Object value) {
+    super.setValue(new ArrayList<>(new TreeSet<>((List<Integer>) value)));
+  }
+
+  @Override
+  public List<Integer> getValue() {
+    return new ArrayList<>(super.getValue());
+  }
 }
diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/error/DecodingException.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/error/DecodingException.java
index 9ea130c1..91c29b2f 100644
--- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/error/DecodingException.java
+++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/error/DecodingException.java
@@ -7,4 +7,12 @@ public class DecodingException extends Exception {
   public DecodingException(String msg) {
     super(msg);
   }
+
+  public DecodingException(Exception e) {
+    super(e);
+  }
+
+  public DecodingException(String msg, Exception e) {
+    super(msg, e);
+  }
 }
diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/error/EncodingException.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/error/EncodingException.java
index 57ec5efb..2c7f80ad 100644
--- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/error/EncodingException.java
+++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/error/EncodingException.java
@@ -7,4 +7,12 @@ public class EncodingException extends Exception {
   public EncodingException(String msg) {
     super(msg);
   }
+
+  public EncodingException(Exception e) {
+    super(e);
+  }
+
+  public EncodingException(String msg, Exception e) {
+    super(msg, e);
+  }
 }
diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/error/InvalidFieldException.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/error/InvalidFieldException.java
new file mode 100644
index 00000000..5b1e1aa9
--- /dev/null
+++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/error/InvalidFieldException.java
@@ -0,0 +1,18 @@
+package com.iab.gpp.encoder.error;
+
+public class InvalidFieldException extends Exception {
+
+  private static final long serialVersionUID = 2098268445119981680L;
+
+  public InvalidFieldException(String msg) {
+    super(msg);
+  }
+
+  public InvalidFieldException(Exception e) {
+    super(e);
+  }
+
+  public InvalidFieldException(String msg, Exception e) {
+    super(msg, e);
+  }
+}
diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractEncodableBitStringSection.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractEncodableBitStringSection.java
index e5648f6c..5b8f0b7c 100644
--- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractEncodableBitStringSection.java
+++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractEncodableBitStringSection.java
@@ -1,9 +1,10 @@
 package com.iab.gpp.encoder.section;
 
 import java.util.Map;
+import com.iab.gpp.encoder.datatype.AbstractEncodableBitStringDataType;
 import com.iab.gpp.encoder.error.DecodingException;
 import com.iab.gpp.encoder.error.EncodingException;
-import com.iab.gpp.encoder.datatype.AbstractEncodableBitStringDataType;
+import com.iab.gpp.encoder.error.InvalidFieldException;
 
 public abstract class AbstractEncodableBitStringSection implements EncodableSection {
   protected Map<String, AbstractEncodableBitStringDataType<?>> fields;
@@ -24,11 +25,11 @@ public Object getFieldValue(String fieldName) {
   }
 
   @Override
-  public void setFieldValue(String fieldName, Object value) {
+  public void setFieldValue(String fieldName, Object value) throws InvalidFieldException {
     if (this.fields.containsKey(fieldName)) {
       this.fields.get(fieldName).setValue(value);
     } else {
-      throw new Error(fieldName + " not found");
+      throw new InvalidFieldException(fieldName + " not found");
     }
   }
 
@@ -44,7 +45,7 @@ public String encodeToBitString() throws EncodingException {
         AbstractEncodableBitStringDataType<?> field = this.fields.get(fieldName);
         bitString += field.encode();
       } else {
-        throw new Error("Field not found: '" + fieldName + "'");
+        throw new EncodingException("Field not found: '" + fieldName + "'");
       }
     }
 
@@ -61,7 +62,7 @@ public void decodeFromBitString(String bitString) throws DecodingException {
         field.decode(substring);
         index += substring.length();
       } else {
-        throw new Error("Field not found: '" + fieldName + "'");
+        throw new DecodingException("Field not found: '" + fieldName + "'");
       }
     }
   }
diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractEncodableSegmentedBitStringSection.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractEncodableSegmentedBitStringSection.java
index c64b45e7..d9339189 100644
--- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractEncodableSegmentedBitStringSection.java
+++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractEncodableSegmentedBitStringSection.java
@@ -3,9 +3,10 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import com.iab.gpp.encoder.datatype.AbstractEncodableBitStringDataType;
 import com.iab.gpp.encoder.error.DecodingException;
 import com.iab.gpp.encoder.error.EncodingException;
-import com.iab.gpp.encoder.datatype.AbstractEncodableBitStringDataType;
+import com.iab.gpp.encoder.error.InvalidFieldException;
 
 public abstract class AbstractEncodableSegmentedBitStringSection implements EncodableSection {
   protected Map<String, AbstractEncodableBitStringDataType<?>> fields;
@@ -26,11 +27,11 @@ public Object getFieldValue(String fieldName) {
   }
 
   @Override
-  public void setFieldValue(String fieldName, Object value) {
+  public void setFieldValue(String fieldName, Object value) throws InvalidFieldException {
     if (this.fields.containsKey(fieldName)) {
       this.fields.get(fieldName).setValue(value);
     } else {
-      throw new Error(fieldName + " not found");
+      throw new InvalidFieldException(fieldName + " not found");
     }
   }
 
@@ -49,10 +50,10 @@ public List<String> encodeSegmentsToBitStrings() throws EncodingException {
             AbstractEncodableBitStringDataType<?> field = this.fields.get(fieldName);
             segmentBitString += field.encode();
           } catch (Exception e) {
-            throw new Error("Unable to encode " + fieldName, e);
+            throw new EncodingException("Unable to encode " + fieldName, e);
           }
         } else {
-          throw new Error("Field not found: '" + fieldName + "'");
+          throw new EncodingException("Field not found: '" + fieldName + "'");
         }
       }
       segmentBitStrings.add(segmentBitString);
@@ -75,10 +76,10 @@ public void decodeSegmentsFromBitStrings(List<String> segmentBitStrings) throws
               field.decode(substring);
               index += substring.length();
             } catch (Exception e) {
-              throw new Error("Unable to decode " + fieldName, e);
+              throw new DecodingException("Unable to decode " + fieldName, e);
             }
           } else {
-            throw new Error("Field not found: '" + fieldName + "'");
+            throw new DecodingException("Field not found: '" + fieldName + "'");
           }
         }
       }
diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/EncodableSection.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/EncodableSection.java
index 9891c5a6..a547e6d3 100644
--- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/EncodableSection.java
+++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/EncodableSection.java
@@ -2,6 +2,7 @@
 
 import com.iab.gpp.encoder.error.DecodingException;
 import com.iab.gpp.encoder.error.EncodingException;
+import com.iab.gpp.encoder.error.InvalidFieldException;
 
 public interface EncodableSection {
 
@@ -13,7 +14,7 @@ public interface EncodableSection {
 
   Object getFieldValue(String fieldName);
 
-  void setFieldValue(String fieldName, Object value);
+  void setFieldValue(String fieldName, Object value) throws InvalidFieldException;
 
   String encode() throws EncodingException;
 
diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfCaV1.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfCaV1.java
index b22dee66..5ff63ada 100644
--- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfCaV1.java
+++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfCaV1.java
@@ -19,6 +19,7 @@
 import com.iab.gpp.encoder.datatype.encoder.CompressedBase64UrlEncoder;
 import com.iab.gpp.encoder.error.DecodingException;
 import com.iab.gpp.encoder.error.EncodingException;
+import com.iab.gpp.encoder.error.InvalidFieldException;
 import com.iab.gpp.encoder.field.TcfCaV1Field;
 
 public class TcfCaV1 extends AbstractEncodableSegmentedBitStringSection {
@@ -43,10 +44,12 @@ public TcfCaV1(String encodedString) throws DecodingException {
   private void initFields() {
     fields = new HashMap<>();
 
+    ZonedDateTime date = ZonedDateTime.now();
+
     // core section
     fields.put(TcfCaV1Field.VERSION, new EncodableFixedInteger(6, TcfCaV1.VERSION));
-    fields.put(TcfCaV1Field.CREATED, new EncodableDatetime());
-    fields.put(TcfCaV1Field.LAST_UPDATED, new EncodableDatetime());
+    fields.put(TcfCaV1Field.CREATED, new EncodableDatetime(date));
+    fields.put(TcfCaV1Field.LAST_UPDATED, new EncodableDatetime(date));
     fields.put(TcfCaV1Field.CMP_ID, new EncodableFixedInteger(12, 0));
     fields.put(TcfCaV1Field.CMP_VERSION, new EncodableFixedInteger(12, 0));
     fields.put(TcfCaV1Field.CONSENT_SCREEN, new EncodableFixedInteger(6, 0));
@@ -54,16 +57,25 @@ private void initFields() {
     fields.put(TcfCaV1Field.VENDOR_LIST_VERSION, new EncodableFixedInteger(12, 0));
     fields.put(TcfCaV1Field.TCF_POLICY_VERSION, new EncodableFixedInteger(6, 2));
     fields.put(TcfCaV1Field.USE_NON_STANDARD_STACKS, new EncodableBoolean(false));
-    fields.put(TcfCaV1Field.SPECIAL_FEATURE_EXPRESS_CONSENT, new EncodableFixedBitfield(12, new ArrayList<>()));
-    fields.put(TcfCaV1Field.PURPOSES_EXPRESS_CONSENT, new EncodableFixedBitfield(24, new ArrayList<>()));
-    fields.put(TcfCaV1Field.PURPOSES_IMPLIED_CONSENT, new EncodableFixedBitfield(24, new ArrayList<>()));
+    fields.put(TcfCaV1Field.SPECIAL_FEATURE_EXPRESS_CONSENT, new EncodableFixedBitfield(
+        Arrays.asList(false, false, false, false, false, false, false, false, false, false, false, false)));
+    fields.put(TcfCaV1Field.PURPOSES_EXPRESS_CONSENT,
+        new EncodableFixedBitfield(Arrays.asList(false, false, false, false, false, false, false, false, false, false,
+            false, false, false, false, false, false, false, false, false, false, false, false, false, false)));
+    fields.put(TcfCaV1Field.PURPOSES_IMPLIED_CONSENT,
+        new EncodableFixedBitfield(Arrays.asList(false, false, false, false, false, false, false, false, false, false,
+            false, false, false, false, false, false, false, false, false, false, false, false, false, false)));
     fields.put(TcfCaV1Field.VENDOR_EXPRESS_CONSENT, new EncodableOptimizedFixedRange(new ArrayList<>()));
     fields.put(TcfCaV1Field.VENDOR_IMPLIED_CONSENT, new EncodableOptimizedFixedRange(new ArrayList<>()));
 
     // publisher purposes segment
     fields.put(TcfCaV1Field.PUB_PURPOSES_SEGMENT_TYPE, new EncodableFixedInteger(3, 3));
-    fields.put(TcfCaV1Field.PUB_PURPOSES_EXPRESS_CONSENT, new EncodableFixedBitfield(24, new ArrayList<>()));
-    fields.put(TcfCaV1Field.PUB_PURPOSES_IMPLIED_CONSENT, new EncodableFixedBitfield(24, new ArrayList<>()));
+    fields.put(TcfCaV1Field.PUB_PURPOSES_EXPRESS_CONSENT,
+        new EncodableFixedBitfield(Arrays.asList(false, false, false, false, false, false, false, false, false, false,
+            false, false, false, false, false, false, false, false, false, false, false, false, false, false)));
+    fields.put(TcfCaV1Field.PUB_PURPOSES_IMPLIED_CONSENT,
+        new EncodableFixedBitfield(Arrays.asList(false, false, false, false, false, false, false, false, false, false,
+            false, false, false, false, false, false, false, false, false, false, false, false, false, false)));
 
     EncodableFixedInteger numCustomPurposes = new EncodableFixedInteger(6, 0);
     fields.put(TcfCaV1Field.NUM_CUSTOM_PURPOSES, numCustomPurposes);
@@ -162,7 +174,7 @@ public void decode(String encodedSection) throws DecodingException {
   }
 
   @Override
-  public void setFieldValue(String fieldName, Object value) {
+  public void setFieldValue(String fieldName, Object value) throws InvalidFieldException {
     super.setFieldValue(fieldName, value);
 
     if (!fieldName.equals(TcfCaV1Field.CREATED) && !fieldName.equals(TcfCaV1Field.LAST_UPDATED)) {
diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfEuV2.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfEuV2.java
index 5ef06409..625121bd 100644
--- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfEuV2.java
+++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfEuV2.java
@@ -20,6 +20,7 @@
 import com.iab.gpp.encoder.datatype.encoder.TraditionalBase64UrlEncoder;
 import com.iab.gpp.encoder.error.DecodingException;
 import com.iab.gpp.encoder.error.EncodingException;
+import com.iab.gpp.encoder.error.InvalidFieldException;
 import com.iab.gpp.encoder.field.TcfEuV2Field;
 
 public class TcfEuV2 extends AbstractEncodableSegmentedBitStringSection {
@@ -44,10 +45,12 @@ public TcfEuV2(String encodedString) throws DecodingException {
   private void initFields() {
     fields = new HashMap<>();
 
+    ZonedDateTime date = ZonedDateTime.now();
+
     // core section
     fields.put(TcfEuV2Field.VERSION, new EncodableFixedInteger(6, TcfEuV2.VERSION));
-    fields.put(TcfEuV2Field.CREATED, new EncodableDatetime());
-    fields.put(TcfEuV2Field.LAST_UPDATED, new EncodableDatetime());
+    fields.put(TcfEuV2Field.CREATED, new EncodableDatetime(date));
+    fields.put(TcfEuV2Field.LAST_UPDATED, new EncodableDatetime(date));
     fields.put(TcfEuV2Field.CMP_ID, new EncodableFixedInteger(12, 0));
     fields.put(TcfEuV2Field.CMP_VERSION, new EncodableFixedInteger(12, 0));
     fields.put(TcfEuV2Field.CONSENT_SCREEN, new EncodableFixedInteger(6, 0));
@@ -56,9 +59,14 @@ private void initFields() {
     fields.put(TcfEuV2Field.POLICY_VERSION, new EncodableFixedInteger(6, 2));
     fields.put(TcfEuV2Field.IS_SERVICE_SPECIFIC, new EncodableBoolean(false));
     fields.put(TcfEuV2Field.USE_NON_STANDARD_STACKS, new EncodableBoolean(false));
-    fields.put(TcfEuV2Field.SPECIAL_FEATURE_OPTINS, new EncodableFixedBitfield(12, new ArrayList<>()));
-    fields.put(TcfEuV2Field.PURPOSE_CONSENTS, new EncodableFixedBitfield(24, new ArrayList<>()));
-    fields.put(TcfEuV2Field.PURPOSE_LEGITIMATE_INTERESTS, new EncodableFixedBitfield(24, new ArrayList<>()));
+    fields.put(TcfEuV2Field.SPECIAL_FEATURE_OPTINS, new EncodableFixedBitfield(
+        Arrays.asList(false, false, false, false, false, false, false, false, false, false, false, false)));
+    fields.put(TcfEuV2Field.PURPOSE_CONSENTS,
+        new EncodableFixedBitfield(Arrays.asList(false, false, false, false, false, false, false, false, false, false,
+            false, false, false, false, false, false, false, false, false, false, false, false, false, false)));
+    fields.put(TcfEuV2Field.PURPOSE_LEGITIMATE_INTERESTS,
+        new EncodableFixedBitfield(Arrays.asList(false, false, false, false, false, false, false, false, false, false,
+            false, false, false, false, false, false, false, false, false, false, false, false, false, false)));
     fields.put(TcfEuV2Field.PURPOSE_ONE_TREATMENT, new EncodableBoolean(false));
     fields.put(TcfEuV2Field.PUBLISHER_COUNTRY_CODE, new EncodableFixedString(2, "AA"));
     fields.put(TcfEuV2Field.VENDOR_CONSENTS, new EncodableOptimizedFixedRange(new ArrayList<>()));
@@ -68,8 +76,12 @@ private void initFields() {
 
     // publisher purposes segment
     fields.put(TcfEuV2Field.PUBLISHER_PURPOSES_SEGMENT_TYPE, new EncodableFixedInteger(3, 3));
-    fields.put(TcfEuV2Field.PUBLISHER_CONSENTS, new EncodableFixedBitfield(24, new ArrayList<>()));
-    fields.put(TcfEuV2Field.PUBLISHER_LEGITIMATE_INTERESTS, new EncodableFixedBitfield(24, new ArrayList<>()));
+    fields.put(TcfEuV2Field.PUBLISHER_CONSENTS,
+        new EncodableFixedBitfield(Arrays.asList(false, false, false, false, false, false, false, false, false, false,
+            false, false, false, false, false, false, false, false, false, false, false, false, false, false)));
+    fields.put(TcfEuV2Field.PUBLISHER_LEGITIMATE_INTERESTS,
+        new EncodableFixedBitfield(Arrays.asList(false, false, false, false, false, false, false, false, false, false,
+            false, false, false, false, false, false, false, false, false, false, false, false, false, false)));
 
     EncodableFixedInteger numCustomPurposes = new EncodableFixedInteger(6, 0);
     fields.put(TcfEuV2Field.NUM_CUSTOM_PURPOSES, numCustomPurposes);
@@ -210,7 +222,7 @@ public void decode(String encodedSection) throws DecodingException {
   }
 
   @Override
-  public void setFieldValue(String fieldName, Object value) {
+  public void setFieldValue(String fieldName, Object value) throws InvalidFieldException {
     super.setFieldValue(fieldName, value);
 
     if (!fieldName.equals(TcfEuV2Field.CREATED) && !fieldName.equals(TcfEuV2Field.LAST_UPDATED)) {
diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UspV1.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UspV1.java
index c267b8d5..cdb20122 100644
--- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UspV1.java
+++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UspV1.java
@@ -2,6 +2,9 @@
 
 import java.util.HashMap;
 import java.util.Map;
+import com.iab.gpp.encoder.error.DecodingException;
+import com.iab.gpp.encoder.error.EncodingException;
+import com.iab.gpp.encoder.error.InvalidFieldException;
 import com.iab.gpp.encoder.field.UspV1LegacyField;
 
 public class UspV1 implements EncodableSection {
@@ -15,7 +18,7 @@ public UspV1() {
     initFields();
   }
 
-  public UspV1(String encodedString) {
+  public UspV1(String encodedString) throws DecodingException {
     initFields();
 
     if (encodedString != null && encodedString.length() > 0) {
@@ -46,16 +49,16 @@ public Object getFieldValue(String fieldName) {
   }
 
   @Override
-  public void setFieldValue(String fieldName, Object value) {
+  public void setFieldValue(String fieldName, Object value) throws InvalidFieldException {
     if (this.fields.containsKey(fieldName)) {
       this.fields.put(fieldName, value);
     } else {
-      throw new Error(fieldName + " not found");
+      throw new InvalidFieldException(fieldName + " not found");
     }
   }
 
   @Override
-  public String encode() {
+  public String encode() throws EncodingException {
     String str = "";
     str += this.getFieldValue(UspV1LegacyField.VERSION);
     str += this.getFieldValue(UspV1LegacyField.NOTICE);
@@ -65,12 +68,15 @@ public String encode() {
   }
 
   @Override
-  public void decode(String encodedString) {
-    // TODO: validate
-    this.setFieldValue(UspV1LegacyField.VERSION, Integer.parseInt(String.valueOf(encodedString.charAt(0))));
-    this.setFieldValue(UspV1LegacyField.NOTICE, String.valueOf(encodedString.charAt(1)));
-    this.setFieldValue(UspV1LegacyField.OPT_OUT_SALE, String.valueOf(encodedString.charAt(2)));
-    this.setFieldValue(UspV1LegacyField.LSPA_COVERED, String.valueOf(encodedString.charAt(3)));
+  public void decode(String encodedString) throws DecodingException {
+    try {
+      this.setFieldValue(UspV1LegacyField.VERSION, Integer.parseInt(String.valueOf(encodedString.charAt(0))));
+      this.setFieldValue(UspV1LegacyField.NOTICE, String.valueOf(encodedString.charAt(1)));
+      this.setFieldValue(UspV1LegacyField.OPT_OUT_SALE, String.valueOf(encodedString.charAt(2)));
+      this.setFieldValue(UspV1LegacyField.LSPA_COVERED, String.valueOf(encodedString.charAt(3)));
+    } catch (InvalidFieldException e) {
+      throw new DecodingException(e);
+    }
   }
 
   @Override
diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/GppModelTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/GppModelTest.java
index 9fdb9f1c..856b06d3 100644
--- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/GppModelTest.java
+++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/GppModelTest.java
@@ -4,10 +4,12 @@
 import java.time.ZonedDateTime;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import com.iab.gpp.encoder.error.DecodingException;
 import com.iab.gpp.encoder.error.EncodingException;
+import com.iab.gpp.encoder.error.InvalidFieldException;
 import com.iab.gpp.encoder.field.TcfCaV1Field;
 import com.iab.gpp.encoder.field.TcfEuV2Field;
 import com.iab.gpp.encoder.field.UspCaV1Field;
@@ -57,7 +59,7 @@ public void testEncodeDefault() throws EncodingException {
   }
 
   @Test
-  public void testEncodeDefaultAll() throws EncodingException {
+  public void testEncodeDefaultAll() throws EncodingException, InvalidFieldException {
     GppModel gppModel = new GppModel();
 
     Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.NAME));
@@ -104,7 +106,7 @@ public void testEncodeDefaultAll() throws EncodingException {
   }
 
   @Test
-  public void testEncodeUspv1() throws EncodingException {
+  public void testEncodeUspv1() throws EncodingException, InvalidFieldException {
     GppModel gppModel = new GppModel();
     Assertions.assertEquals(false, gppModel.hasSection(UspV1.ID));
     Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.ID));
@@ -144,7 +146,7 @@ public void testEncodeUspv1() throws EncodingException {
   }
 
   @Test
-  public void testEncodeTcfEuV2() throws EncodingException {
+  public void testEncodeTcfEuV2() throws EncodingException, InvalidFieldException {
     GppModel gppModel = new GppModel();
     Assertions.assertEquals(false, gppModel.hasSection(UspV1.ID));
     Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.ID));
@@ -194,7 +196,7 @@ public void testEncodeTcfEuV2() throws EncodingException {
   }
 
   @Test
-  public void testEncodeUspV1AndTcfEuV2() throws EncodingException {
+  public void testEncodeUspV1AndTcfEuV2() throws EncodingException, InvalidFieldException {
     GppModel gppModel = new GppModel();
     Assertions.assertEquals(false, gppModel.hasSection(UspV1.NAME));
     Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.NAME));
@@ -239,7 +241,7 @@ public void testEncodeUspV1AndTcfEuV2() throws EncodingException {
   }
 
   @Test
-  public void testEncodeUspV1AndTcfEuV2AndTcfCaV1() throws EncodingException {
+  public void testEncodeUspV1AndTcfEuV2AndTcfCaV1() throws EncodingException, InvalidFieldException {
     GppModel gppModel = new GppModel();
     Assertions.assertEquals(false, gppModel.hasSection(UspV1.ID));
     Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.ID));
@@ -583,4 +585,80 @@ public void testDecodeUspv1AndTcfEuV2AndTcfCaV1() throws DecodingException {
     Assertions.assertEquals(3, tcfCaV1Section.getPubPurposesSegmentType());
   }
 
+  @Test
+  public void testEncode1() throws EncodingException, InvalidFieldException {
+    GppModel gppModel = new GppModel();
+
+    gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.VENDOR_CONSENTS, Arrays.asList(28));
+    gppModel.setFieldValue(TcfEuV2.NAME, TcfCaV1Field.CREATED, utcDateTime);
+    gppModel.setFieldValue(TcfEuV2.NAME, TcfCaV1Field.LAST_UPDATED, utcDateTime);
+
+    Assertions.assertEquals("DBABMA~CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAOAAAABAAAAA.QAAA.IAAA", gppModel.encode());
+  }
+
+  @Test
+  public void testEncode2() throws EncodingException, InvalidFieldException {
+    GppModel gppModel = new GppModel();
+
+    gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.VENDOR_CONSENTS, Arrays.asList(29));
+    gppModel.setFieldValue(TcfEuV2.NAME, TcfCaV1Field.CREATED, utcDateTime);
+    gppModel.setFieldValue(TcfEuV2.NAME, TcfCaV1Field.LAST_UPDATED, utcDateTime);
+
+    Assertions.assertEquals("DBABMA~CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAOwAQAOgAAAA.QAAA.IAAA", gppModel.encode());
+  }
+
+  @Test
+  public void testEncode3() throws EncodingException, InvalidFieldException {
+    GppModel gppModel = new GppModel();
+
+    gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.VENDOR_CONSENTS, Arrays.asList(1, 173, 722));
+    gppModel.setFieldValue(TcfEuV2.NAME, TcfCaV1Field.CREATED, utcDateTime);
+    gppModel.setFieldValue(TcfEuV2.NAME, TcfCaV1Field.LAST_UPDATED, utcDateTime);
+
+    Assertions.assertEquals("DBABMA~CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAFpQAwAAgCtAWkAAAAAAA.QAAA.IAAA",
+        gppModel.encode());
+  }
+
+  @Test
+  public void testDecode1() throws DecodingException {
+    GppModel gppModel = new GppModel("DBABMA~CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAOAAAABAAAAA.QAAA.IAAA");
+    Assertions.assertEquals(Arrays.asList(28), gppModel.getFieldValue(TcfEuV2.NAME, TcfEuV2Field.VENDOR_CONSENTS));
+  }
+
+  @Test
+  public void testDecode2() throws DecodingException {
+    GppModel gppModel = new GppModel("DBABMA~CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAOwAQAOgAAAA.QAAA.IAAA");
+    Assertions.assertEquals(Arrays.asList(29), gppModel.getFieldValue(TcfEuV2.NAME, TcfEuV2Field.VENDOR_CONSENTS));
+  }
+
+  @Test
+  public void testDecode3() throws DecodingException {
+    GppModel gppModel = new GppModel("DBABMA~CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAFpQAwAAgCtAWkAAAAAAA.QAAA.IAAA");
+    Assertions.assertEquals(Arrays.asList(1, 173, 722),
+        gppModel.getFieldValue(TcfEuV2.NAME, TcfEuV2Field.VENDOR_CONSENTS));
+  }
+
+  @Test
+  public void testConsistency() throws InvalidFieldException, EncodingException, DecodingException {
+    GppModel fromObjectModel = new GppModel();
+
+    fromObjectModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.PURPOSE_CONSENTS,
+        new ArrayList<>(List.of(true, true, true, true, true, true, true, true, true, true)));
+    fromObjectModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.VENDOR_CONSENTS,
+        new ArrayList<>(List.of(32, 128, 81, 210, 755, 21, 173, 238)));
+
+    Assertions.assertEquals(fromObjectModel.getSection(TcfEuV2.NAME).encode(),
+        fromObjectModel.getSection(TcfEuV2.NAME).encode());
+    Assertions.assertEquals(fromObjectModel.encode(), fromObjectModel.encode());
+
+    GppModel decodedModel = new GppModel(fromObjectModel.encode());
+
+    Assertions.assertEquals(
+        new ArrayList<>(List.of(true, true, true, true, true, true, true, true, true, true, false, false, false, false,
+            false, false, false, false, false, false, false, false, false, false)),
+        decodedModel.getFieldValue(TcfEuV2.NAME, TcfEuV2Field.PURPOSE_CONSENTS));
+    Assertions.assertEquals(new ArrayList<>(List.of(21, 32, 81, 128, 173, 210, 238, 755)),
+        decodedModel.getFieldValue(TcfEuV2.NAME, TcfEuV2Field.VENDOR_CONSENTS));
+
+  }
 }
diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerRangeTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerRangeTest.java
index 51d71a2f..51a16c39 100644
--- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerRangeTest.java
+++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerRangeTest.java
@@ -1,5 +1,6 @@
 package com.iab.gpp.encoder.datatype;
 
+import java.util.Arrays;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import com.iab.gpp.encoder.error.DecodingException;
@@ -13,4 +14,39 @@ public void testSubstring1() throws DecodingException {
             1));
   }
 
+  @Test
+  public void testSubstring2() throws DecodingException {
+    Assertions.assertEquals("00000000000100000000000011101", new EncodableFixedIntegerRange().substring(
+        "000010001111010010000110111111111100000000001111010010000110111111111100000000000000000000000000000000000000000100001101000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000001110110000000000010000000000001110100000000000000000000000000000",
+        230));
+  }
+
+  @Test
+  public void testEncode1() {
+    EncodableFixedIntegerRange encodableFixedIntegerRange = new EncodableFixedIntegerRange();
+    encodableFixedIntegerRange.setValue(Arrays.asList(28));
+    Assertions.assertEquals("00000000000100000000000011100", encodableFixedIntegerRange.encode());
+  }
+
+  @Test
+  public void testEncode2() {
+    EncodableFixedIntegerRange encodableFixedIntegerRange = new EncodableFixedIntegerRange();
+    encodableFixedIntegerRange.setValue(Arrays.asList(29));
+    Assertions.assertEquals("00000000000100000000000011101", encodableFixedIntegerRange.encode());
+  }
+
+  @Test
+  public void testDecode1() throws DecodingException {
+    EncodableFixedIntegerRange encodableFixedIntegerRange = new EncodableFixedIntegerRange();
+    encodableFixedIntegerRange.decode("00000000000100000000000011100");
+    Assertions.assertEquals(Arrays.asList(28), encodableFixedIntegerRange.getValue());
+  }
+
+  @Test
+  public void testDecode2() throws DecodingException {
+    EncodableFixedIntegerRange encodableFixedIntegerRange = new EncodableFixedIntegerRange();
+    encodableFixedIntegerRange.decode("00000000000100000000000011101");
+    Assertions.assertEquals(Arrays.asList(29), encodableFixedIntegerRange.getValue());
+  }
+
 }
diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFixedRangeTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFixedRangeTest.java
index f1075faf..73af6f6e 100644
--- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFixedRangeTest.java
+++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFixedRangeTest.java
@@ -23,6 +23,18 @@ public void testEncode2() throws EncodingException {
     Assertions.assertEquals("00000000000111100000000000000000001000000000001", encodableOptimizedFixedRange.encode());
   }
 
+  @Test
+  public void testEncode3() throws EncodingException {
+    encodableOptimizedFixedRange.setValue(Arrays.asList(28));
+    Assertions.assertEquals("000000000001110000000000000000000000000000001", encodableOptimizedFixedRange.encode());
+  }
+
+  @Test
+  public void testEncode4() throws EncodingException {
+    encodableOptimizedFixedRange.setValue(Arrays.asList(29));
+    Assertions.assertEquals("0000000000011101100000000000100000000000011101", encodableOptimizedFixedRange.encode());
+  }
+
   @Test
   public void testDecode1() throws DecodingException {
     encodableOptimizedFixedRange.decode("00000000001100000000000000001000000000001000000000000000000000001");
@@ -34,4 +46,30 @@ public void testDecode2() throws DecodingException {
     encodableOptimizedFixedRange.decode("00000000000111100000000000000000001000000000001");
     Assertions.assertEquals(Arrays.asList(18, 30), encodableOptimizedFixedRange.getValue());
   }
+
+  @Test
+  public void testDecode3() throws DecodingException {
+    encodableOptimizedFixedRange.decode("000000000001110000000000000000000000000000001");
+    Assertions.assertEquals(Arrays.asList(28), encodableOptimizedFixedRange.getValue());
+  }
+
+  @Test
+  public void testDecode4() throws DecodingException {
+    encodableOptimizedFixedRange.decode("0000000000011101100000000000100000000000011101");
+    Assertions.assertEquals(Arrays.asList(29), encodableOptimizedFixedRange.getValue());
+  }
+
+  @Test
+  public void testSubstring1() throws DecodingException {
+    Assertions.assertEquals("000000000001110000000000000000000000000000001", encodableOptimizedFixedRange.substring(
+        "000010001111010010000110111111111100000000001111010010000110111111111100000000000000000000000000000000000000000100001101000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000001110000000000000000000000000000001000000000000000000000000000000",
+        213));
+  }
+
+  @Test
+  public void testSubstring2() throws DecodingException {
+    Assertions.assertEquals("0000000000011101100000000000100000000000011101", encodableOptimizedFixedRange.substring(
+        "000010001111010010000110111111111100000000001111010010000110111111111100000000000000000000000000000000000000000100001101000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000001110110000000000010000000000001110100000000000000000000000000000",
+        213));
+  }
 }
diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/HeaderV1Test.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/HeaderV1Test.java
index 7c83d58b..4c74ec5a 100644
--- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/HeaderV1Test.java
+++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/HeaderV1Test.java
@@ -6,25 +6,26 @@
 import org.junit.jupiter.api.Test;
 import com.iab.gpp.encoder.error.DecodingException;
 import com.iab.gpp.encoder.error.EncodingException;
+import com.iab.gpp.encoder.error.InvalidFieldException;
 
 public class HeaderV1Test {
 
   @Test
-  public void testEncodeToBitString1() throws EncodingException {
+  public void testEncodeToBitString1() throws EncodingException, InvalidFieldException {
     HeaderV1 headerV1 = new HeaderV1();
     headerV1.setFieldValue("SectionIds", new ArrayList<>());
     Assertions.assertEquals("000011000001000000000000", headerV1.encodeToBitString());
   }
 
   @Test
-  public void testEncodeToBitString2() throws EncodingException {
+  public void testEncodeToBitString2() throws EncodingException, InvalidFieldException {
     HeaderV1 headerV1 = new HeaderV1();
     headerV1.setFieldValue("SectionIds", Arrays.asList(2));
     Assertions.assertEquals("0000110000010000000000010011", headerV1.encodeToBitString());
   }
 
   @Test
-  public void testEncodeToBitString3() throws EncodingException {
+  public void testEncodeToBitString3() throws EncodingException, InvalidFieldException {
     HeaderV1 headerV1 = new HeaderV1();
     headerV1.setFieldValue("SectionIds", Arrays.asList(2, 6));
     Assertions.assertEquals("000011000001000000000010001101011", headerV1.encodeToBitString());
@@ -55,21 +56,21 @@ public void testDecodeFromBitString3() throws DecodingException {
   }
 
   @Test
-  public void testEncode1() throws EncodingException {
+  public void testEncode1() throws EncodingException, InvalidFieldException {
     HeaderV1 headerV1 = new HeaderV1();
     headerV1.setFieldValue("SectionIds", new ArrayList<>());
     Assertions.assertEquals("DBAA", headerV1.encode());
   }
 
   @Test
-  public void testEncode2() throws EncodingException {
+  public void testEncode2() throws EncodingException, InvalidFieldException {
     HeaderV1 headerV1 = new HeaderV1();
     headerV1.setFieldValue("SectionIds", Arrays.asList(2));
     Assertions.assertEquals("DBABMA", headerV1.encode());
   }
 
   @Test
-  public void testEncode3() throws EncodingException {
+  public void testEncode3() throws EncodingException, InvalidFieldException {
     HeaderV1 headerV1 = new HeaderV1();
     headerV1.setFieldValue("SectionIds", Arrays.asList(2, 6));
     Assertions.assertEquals("DBACNYA", headerV1.encode());
diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/TcfCaV1Test.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/TcfCaV1Test.java
index d1738f1a..fdb14e04 100644
--- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/TcfCaV1Test.java
+++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/TcfCaV1Test.java
@@ -8,19 +8,22 @@
 import org.junit.jupiter.api.Test;
 import com.iab.gpp.encoder.error.DecodingException;
 import com.iab.gpp.encoder.error.EncodingException;
+import com.iab.gpp.encoder.error.InvalidFieldException;
 import com.iab.gpp.encoder.field.TcfCaV1Field;
 
 public class TcfCaV1Test {
 
   @Test
-  public void testEncode1() throws EncodingException {
+  public void testEncode1() throws EncodingException, InvalidFieldException {
 
     TcfCaV1 tcfCaV1 = new TcfCaV1();
-    Assertions.assertEquals("CAAAAAAAAAAAAAAAAAENAACAAAAAAAAAAAAAAAAA.YAAAAAAAAAA", tcfCaV1.encode());
+    tcfCaV1.setFieldValue(TcfCaV1Field.CREATED, ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC")));
+    tcfCaV1.setFieldValue(TcfCaV1Field.LAST_UPDATED, ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC")));
+    Assertions.assertEquals("CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAA.YAAAAAAAAAA", tcfCaV1.encode());
   }
 
   @Test
-  public void testEncode2() throws EncodingException {
+  public void testEncode2() throws EncodingException, InvalidFieldException {
 
     TcfCaV1 tcfCaV1 = new TcfCaV1();
     tcfCaV1.setFieldValue(TcfCaV1Field.CMP_ID, 50);
diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/TcfEuV2Test.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/TcfEuV2Test.java
index c8d5cc9a..20eb2a7b 100644
--- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/TcfEuV2Test.java
+++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/TcfEuV2Test.java
@@ -8,18 +8,21 @@
 import org.junit.jupiter.api.Test;
 import com.iab.gpp.encoder.error.DecodingException;
 import com.iab.gpp.encoder.error.EncodingException;
+import com.iab.gpp.encoder.error.InvalidFieldException;
 import com.iab.gpp.encoder.field.TcfEuV2Field;
 
 public class TcfEuV2Test {
 
   @Test
-  public void testEncode1() throws EncodingException {
+  public void testEncode1() throws EncodingException, InvalidFieldException {
     TcfEuV2 tcfEuV2 = new TcfEuV2();
-    Assertions.assertEquals("CAAAAAAAAAAAAAAAAAENAACAAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA", tcfEuV2.encode());
+    tcfEuV2.setFieldValue(TcfEuV2Field.CREATED, ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC")));
+    tcfEuV2.setFieldValue(TcfEuV2Field.LAST_UPDATED, ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC")));
+    Assertions.assertEquals("CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA", tcfEuV2.encode());
   }
 
   @Test
-  public void testEncode2() throws EncodingException {
+  public void testEncode2() throws EncodingException, InvalidFieldException {
     TcfEuV2 tcfEuV2 = new TcfEuV2();
     tcfEuV2.setFieldValue(TcfEuV2Field.IS_SERVICE_SPECIFIC, true);
     tcfEuV2.setFieldValue(TcfEuV2Field.CREATED, ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC")));
@@ -60,8 +63,15 @@ public void testDecode1() throws DecodingException {
     Assertions.assertEquals(Arrays.asList(), tcfEuV2.getVendorLegitimateInterests());
     Assertions.assertEquals(Arrays.asList(), tcfEuV2.getPublisherRestrictions());
     Assertions.assertEquals(3, tcfEuV2.getPublisherPurposesSegmentType());
-    Assertions.assertEquals(Arrays.asList(), tcfEuV2.getPublisherConsents());
-    Assertions.assertEquals(Arrays.asList(), tcfEuV2.getPublisherLegitimateInterests());
+    Assertions
+        .assertEquals(
+            Arrays.asList(false, false, false, false, false, false, false, false, false, false, false, false, false,
+                false, false, false, false, false, false, false, false, false, false, false),
+            tcfEuV2.getPublisherConsents());
+    Assertions.assertEquals(
+        Arrays.asList(false, false, false, false, false, false, false, false, false, false, false, false, false, false,
+            false, false, false, false, false, false, false, false, false, false),
+        tcfEuV2.getPublisherLegitimateInterests());
     Assertions.assertEquals(0, tcfEuV2.getNumCustomPurposes());
     Assertions.assertEquals(Arrays.asList(), tcfEuV2.getPublisherCustomConsents());
     Assertions.assertEquals(Arrays.asList(), tcfEuV2.getPublisherCustomLegitimateInterests());
diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspCaV1Test.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspCaV1Test.java
index 1e642d3a..0848536b 100644
--- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspCaV1Test.java
+++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspCaV1Test.java
@@ -6,6 +6,7 @@
 import org.junit.jupiter.api.Test;
 import com.iab.gpp.encoder.error.DecodingException;
 import com.iab.gpp.encoder.error.EncodingException;
+import com.iab.gpp.encoder.error.InvalidFieldException;
 import com.iab.gpp.encoder.field.UspCaV1Field;
 
 public class UspCaV1Test {
@@ -18,7 +19,7 @@ public void testEncode1() throws EncodingException {
   }
 
   @Test
-  public void testEncode2() throws EncodingException {
+  public void testEncode2() throws EncodingException, InvalidFieldException {
     UspCaV1 uspCaV1 = new UspCaV1();
 
     uspCaV1.setFieldValue(UspCaV1Field.SALE_OPT_OUT_NOTICE, 1);
@@ -38,7 +39,7 @@ public void testEncode2() throws EncodingException {
   }
 
   @Test
-  public void testEncode3() throws EncodingException {
+  public void testEncode3() throws EncodingException, InvalidFieldException {
     UspCaV1 uspCaV1 = new UspCaV1();
 
     uspCaV1.setFieldValue(UspCaV1Field.SALE_OPT_OUT_NOTICE, 1);
@@ -58,7 +59,7 @@ public void testEncode3() throws EncodingException {
   }
 
   @Test
-  public void testEncodeWithGpcSegmentExcluded() throws EncodingException {
+  public void testEncodeWithGpcSegmentExcluded() throws EncodingException, InvalidFieldException {
 
     UspCaV1 uspCaV1 = new UspCaV1();
     uspCaV1.setFieldValue(UspCaV1Field.GPC_SEGMENT_INCLUDED, false);
diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspCoV1Test.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspCoV1Test.java
index 91d00952..05559ca9 100644
--- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspCoV1Test.java
+++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspCoV1Test.java
@@ -6,6 +6,7 @@
 import org.junit.jupiter.api.Test;
 import com.iab.gpp.encoder.error.DecodingException;
 import com.iab.gpp.encoder.error.EncodingException;
+import com.iab.gpp.encoder.error.InvalidFieldException;
 import com.iab.gpp.encoder.field.UspCoV1Field;
 
 public class UspCoV1Test {
@@ -17,7 +18,7 @@ public void testEncode1() throws EncodingException {
   }
 
   @Test
-  public void testEncode2() throws EncodingException {
+  public void testEncode2() throws EncodingException, InvalidFieldException {
     UspCoV1 uspCoV1 = new UspCoV1();
 
     uspCoV1.setFieldValue(UspCoV1Field.SHARING_NOTICE, 1);
@@ -36,7 +37,7 @@ public void testEncode2() throws EncodingException {
   }
 
   @Test
-  public void testEncodeWithGpcSegmentExcluded() throws EncodingException {
+  public void testEncodeWithGpcSegmentExcluded() throws EncodingException, InvalidFieldException {
     UspCoV1 uspCoV1 = new UspCoV1();
     uspCoV1.setFieldValue(UspCoV1Field.GPC_SEGMENT_INCLUDED, false);
     Assertions.assertEquals("BAAAAAA", uspCoV1.encode());
diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspCtV1Test.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspCtV1Test.java
index bb10e025..efc382f8 100644
--- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspCtV1Test.java
+++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspCtV1Test.java
@@ -6,6 +6,7 @@
 import org.junit.jupiter.api.Test;
 import com.iab.gpp.encoder.error.DecodingException;
 import com.iab.gpp.encoder.error.EncodingException;
+import com.iab.gpp.encoder.error.InvalidFieldException;
 import com.iab.gpp.encoder.field.UspCtV1Field;
 
 public class UspCtV1Test {
@@ -17,7 +18,7 @@ public void testEncode1() throws EncodingException {
   }
 
   @Test
-  public void testEncode2() throws EncodingException {
+  public void testEncode2() throws EncodingException, InvalidFieldException {
     UspCtV1 uspCtV1 = new UspCtV1();
 
     uspCtV1.setFieldValue(UspCtV1Field.SHARING_NOTICE, 1);
@@ -36,7 +37,7 @@ public void testEncode2() throws EncodingException {
   }
 
   @Test
-  public void testEncodeWithGpcSegmentExcluded() throws EncodingException {
+  public void testEncodeWithGpcSegmentExcluded() throws EncodingException, InvalidFieldException {
     UspCtV1 uspCtV1 = new UspCtV1();
     uspCtV1.setFieldValue(UspCtV1Field.GPC_SEGMENT_INCLUDED, false);
     Assertions.assertEquals("BAAAAAAA", uspCtV1.encode());
diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspNatV1Test.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspNatV1Test.java
index fa647c2f..b70e07c9 100644
--- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspNatV1Test.java
+++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspNatV1Test.java
@@ -6,6 +6,7 @@
 import org.junit.jupiter.api.Test;
 import com.iab.gpp.encoder.error.DecodingException;
 import com.iab.gpp.encoder.error.EncodingException;
+import com.iab.gpp.encoder.error.InvalidFieldException;
 import com.iab.gpp.encoder.field.UspNatV1Field;
 
 public class UspNatV1Test {
@@ -18,7 +19,7 @@ public void testEncode1() throws EncodingException {
   }
 
   @Test
-  public void testEncode2() throws EncodingException {
+  public void testEncode2() throws EncodingException, InvalidFieldException {
     UspNatV1 uspNatV1 = new UspNatV1();
 
     uspNatV1.setFieldValue(UspNatV1Field.SHARING_NOTICE, 1);
@@ -42,7 +43,7 @@ public void testEncode2() throws EncodingException {
   }
 
   @Test
-  public void testEncode3() throws EncodingException {
+  public void testEncode3() throws EncodingException, InvalidFieldException {
     UspNatV1 uspNatV1 = new UspNatV1();
 
     uspNatV1.setFieldValue(UspNatV1Field.SHARING_NOTICE, 1);
@@ -66,7 +67,7 @@ public void testEncode3() throws EncodingException {
   }
 
   @Test
-  public void testEncodeWithGpcSegmentIncluded() throws EncodingException {
+  public void testEncodeWithGpcSegmentIncluded() throws EncodingException, InvalidFieldException {
 
     UspNatV1 uspNatV1 = new UspNatV1();
     uspNatV1.setFieldValue(UspNatV1Field.GPC_SEGMENT_INCLUDED, false);
diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspUtV1Test.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspUtV1Test.java
index 3c3312f5..5bad0d1f 100644
--- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspUtV1Test.java
+++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspUtV1Test.java
@@ -6,6 +6,7 @@
 import org.junit.jupiter.api.Test;
 import com.iab.gpp.encoder.error.DecodingException;
 import com.iab.gpp.encoder.error.EncodingException;
+import com.iab.gpp.encoder.error.InvalidFieldException;
 import com.iab.gpp.encoder.field.UspUtV1Field;
 
 public class UspUtV1Test {
@@ -17,7 +18,7 @@ public void testEncode1() throws EncodingException {
   }
 
   @Test
-  public void testEncode2() throws EncodingException {
+  public void testEncode2() throws EncodingException, InvalidFieldException {
     UspUtV1 uspUtV1 = new UspUtV1();
 
     uspUtV1.setFieldValue(UspUtV1Field.SHARING_NOTICE, 1);
diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspV1Test.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspV1Test.java
index 228b346f..13eb280d 100644
--- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspV1Test.java
+++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspV1Test.java
@@ -2,7 +2,9 @@
 
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
+import com.iab.gpp.encoder.error.DecodingException;
 import com.iab.gpp.encoder.error.EncodingException;
+import com.iab.gpp.encoder.error.InvalidFieldException;
 
 public class UspV1Test {
 
@@ -13,7 +15,7 @@ public void testEncode1() throws EncodingException {
   }
 
   @Test
-  public void testEncode2() throws EncodingException {
+  public void testEncode2() throws EncodingException, InvalidFieldException {
     UspV1 uspv1 = new UspV1();
     uspv1.setFieldValue("Notice", "Y");
     uspv1.setFieldValue("OptOutSale", "N");
@@ -23,7 +25,7 @@ public void testEncode2() throws EncodingException {
   }
 
   @Test
-  public void testEncode3() throws EncodingException {
+  public void testEncode3() throws EncodingException, InvalidFieldException {
     UspV1 uspv1 = new UspV1();
     uspv1.setFieldValue("Version", 2);
     uspv1.setFieldValue("Notice", "N");
@@ -34,7 +36,7 @@ public void testEncode3() throws EncodingException {
   }
 
   @Test
-  public void testDecode1() throws EncodingException {
+  public void testDecode1() throws DecodingException, InvalidFieldException {
     UspV1 uspv1 = new UspV1("1NYN");
     Assertions.assertEquals(1, uspv1.getFieldValue("Version"));
     Assertions.assertEquals("N", uspv1.getFieldValue("Notice"));
@@ -48,7 +50,7 @@ public void testDecode1() throws EncodingException {
   }
 
   @Test
-  public void testDecode2() throws EncodingException {
+  public void testDecode2() throws DecodingException, InvalidFieldException {
     UspV1 uspv1 = new UspV1("2YNY");
     Assertions.assertEquals(2, uspv1.getFieldValue("Version"));
     Assertions.assertEquals("Y", uspv1.getFieldValue("Notice"));
diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspVaV1Test.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspVaV1Test.java
index c15f4246..a8f38633 100644
--- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspVaV1Test.java
+++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspVaV1Test.java
@@ -6,6 +6,7 @@
 import org.junit.jupiter.api.Test;
 import com.iab.gpp.encoder.error.DecodingException;
 import com.iab.gpp.encoder.error.EncodingException;
+import com.iab.gpp.encoder.error.InvalidFieldException;
 import com.iab.gpp.encoder.field.UspVaV1Field;
 
 public class UspVaV1Test {
@@ -20,16 +21,20 @@ public void testEncode1() throws EncodingException {
   public void testEncode2() throws EncodingException {
     UspVaV1 uspVaV1 = new UspVaV1();
 
-    uspVaV1.setFieldValue(UspVaV1Field.SHARING_NOTICE, 1);
-    uspVaV1.setFieldValue(UspVaV1Field.SALE_OPT_OUT_NOTICE, 2);
-    uspVaV1.setFieldValue(UspVaV1Field.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 3);
-    uspVaV1.setFieldValue(UspVaV1Field.SALE_OPT_OUT, 1);
-    uspVaV1.setFieldValue(UspVaV1Field.TARGETED_ADVERTISING_OPT_OUT, 2);
-    uspVaV1.setFieldValue(UspVaV1Field.SENSITIVE_DATA_PROCESSING, Arrays.asList(0, 1, 2, 3, 0, 1, 2, 3));
-    uspVaV1.setFieldValue(UspVaV1Field.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 3);
-    uspVaV1.setFieldValue(UspVaV1Field.MSPA_COVERED_TRANSACTION, 1);
-    uspVaV1.setFieldValue(UspVaV1Field.MSPA_OPT_OUT_OPTION_MODE, 2);
-    uspVaV1.setFieldValue(UspVaV1Field.MSPA_SERVICE_PROVIDER_MODE, 3);
+    try {
+      uspVaV1.setFieldValue(UspVaV1Field.SHARING_NOTICE, 1);
+      uspVaV1.setFieldValue(UspVaV1Field.SALE_OPT_OUT_NOTICE, 2);
+      uspVaV1.setFieldValue(UspVaV1Field.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 3);
+      uspVaV1.setFieldValue(UspVaV1Field.SALE_OPT_OUT, 1);
+      uspVaV1.setFieldValue(UspVaV1Field.TARGETED_ADVERTISING_OPT_OUT, 2);
+      uspVaV1.setFieldValue(UspVaV1Field.SENSITIVE_DATA_PROCESSING, Arrays.asList(0, 1, 2, 3, 0, 1, 2, 3));
+      uspVaV1.setFieldValue(UspVaV1Field.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 3);
+      uspVaV1.setFieldValue(UspVaV1Field.MSPA_COVERED_TRANSACTION, 1);
+      uspVaV1.setFieldValue(UspVaV1Field.MSPA_OPT_OUT_OPTION_MODE, 2);
+      uspVaV1.setFieldValue(UspVaV1Field.MSPA_SERVICE_PROVIDER_MODE, 3);
+    } catch (InvalidFieldException e) {
+      throw new EncodingException(e);
+    }
 
     Assertions.assertEquals("BbYbG9s", uspVaV1.encode());
   }
diff --git a/iabgpp-extras-jackson/pom.xml b/iabgpp-extras-jackson/pom.xml
index 47cef939..ff4d7860 100644
--- a/iabgpp-extras-jackson/pom.xml
+++ b/iabgpp-extras-jackson/pom.xml
@@ -7,7 +7,7 @@
     <parent>
         <artifactId>iabgpp-core</artifactId>
         <groupId>com.iabgpp</groupId>
-        <version>3.0.8-SNAPSHOT</version>
+        <version>3.0.11-SNAPSHOT</version>
     </parent>
 
     <artifactId>iabgpp-extras-jackson</artifactId>
@@ -24,7 +24,7 @@
         <dependency>
             <groupId>com.iabgpp</groupId>
             <artifactId>iabgpp-extras</artifactId>
-            <version>3.0.8-SNAPSHOT</version>
+            <version>3.0.11-SNAPSHOT</version>
         </dependency>
 
         <dependency>
diff --git a/iabgpp-extras/pom.xml b/iabgpp-extras/pom.xml
index bf1979a0..35fda85f 100644
--- a/iabgpp-extras/pom.xml
+++ b/iabgpp-extras/pom.xml
@@ -7,7 +7,7 @@
     <parent>
         <groupId>com.iabgpp</groupId>
         <artifactId>iabgpp-core</artifactId>
-        <version>3.0.8-SNAPSHOT</version>
+        <version>3.0.11-SNAPSHOT</version>
     </parent>
 
     <artifactId>iabgpp-extras</artifactId>
diff --git a/pom.xml b/pom.xml
index dbd2062f..bad74e4c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
 
     <groupId>com.iabgpp</groupId>
     <artifactId>iabgpp-core</artifactId>
-    <version>3.0.8-SNAPSHOT</version>
+    <version>3.0.11-SNAPSHOT</version>
     <name>IAB GPP Core Library</name>
     <url>https://github.com/IABTechLabs/iabtcf-java</url>
     <description>Encode and decode consent information with the IAB GPP v3.0.</description>
