diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/ScellAdd.java b/src/main/java/org.onosproject.xran/codecs/pdu/ScellAdd.java
index a1d6c8f..3ee1f02 100644
--- a/src/main/java/org.onosproject.xran/codecs/pdu/ScellAdd.java
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/ScellAdd.java
@@ -10,321 +10,355 @@
 import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
 import org.openmuc.jasn1.ber.BerLength;
 import org.openmuc.jasn1.ber.BerTag;
+import org.openmuc.jasn1.ber.types.BerBoolean;
+import org.openmuc.jasn1.ber.types.BerEnum;
+import org.openmuc.jasn1.ber.types.BerInteger;
+import org.openmuc.jasn1.ber.types.string.BerUTF8String;
 
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
 public class ScellAdd implements Serializable {
 
-	private static final long serialVersionUID = 1L;
+    public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+    private static final long serialVersionUID = 1L;
+    public byte[] code = null;
+    private CRNTI crnti = null;
+    private ECGI ecgi = null;
+    private ScellsProp scellsProp = null;
+    public ScellAdd() {
+    }
+    public ScellAdd(byte[] code) {
+        this.code = code;
+    }
 
-	public static class ScellsProp implements Serializable {
+    public static XrancPdu constructPacket(ECGI ecgi, CRNTI crnti, PropScell propScell) {
+        ScellAdd scellAdd = new ScellAdd();
+        scellAdd.setCrnti(crnti);
+        scellAdd.setEcgi(ecgi);
 
-		private static final long serialVersionUID = 1L;
+        propScell.setCrossCarrierSchedEnable(new BerBoolean(true));
+        propScell.setCaDirection(new BerEnum(new BigInteger("dl")));
+        propScell.setDeactTimer(new BerInteger(1000));
+        ScellsProp scellsProp = new ScellsProp();
+        scellsProp.addPropScell(propScell);
+        scellAdd.setScellsProp(scellsProp);
 
-		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
-		public byte[] code = null;
-		private List<PropScell> seqOf = null;
+        XrancPduBody body = new XrancPduBody();
+        body.setScellAdd(scellAdd);
 
-		public ScellsProp() {
-			seqOf = new ArrayList<PropScell>();
-		}
+        BerUTF8String ver = null;
+        try {
+            ver = new BerUTF8String("3");
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        XrancApiID apiID = new XrancApiID(26);
+        XrancPduHdr hdr = new XrancPduHdr();
+        hdr.setVer(ver);
+        hdr.setApiId(apiID);
 
-		public ScellsProp(byte[] code) {
-			this.code = code;
-		}
+        XrancPdu pdu = new XrancPdu();
+        pdu.setHdr(hdr);
+        pdu.setBody(body);
 
-		public List<PropScell> getPropScell() {
-			if (seqOf == null) {
-				seqOf = new ArrayList<PropScell>();
-			}
-			return seqOf;
-		}
+        return pdu;
+    }
 
-		public int encode(BerByteArrayOutputStream os) throws IOException {
-			return encode(os, true);
-		}
+    public CRNTI getCrnti() {
+        return crnti;
+    }
 
-		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+    public void setCrnti(CRNTI crnti) {
+        this.crnti = crnti;
+    }
 
-			if (code != null) {
-				for (int i = code.length - 1; i >= 0; i--) {
-					os.write(code[i]);
-				}
-				if (withTag) {
-					return tag.encode(os) + code.length;
-				}
-				return code.length;
-			}
+    public ECGI getEcgi() {
+        return ecgi;
+    }
 
-			int codeLength = 0;
-			for (int i = (seqOf.size() - 1); i >= 0; i--) {
-				codeLength += seqOf.get(i).encode(os, true);
-			}
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
 
-			codeLength += BerLength.encodeLength(os, codeLength);
+    public ScellsProp getScellsProp() {
+        return scellsProp;
+    }
 
-			if (withTag) {
-				codeLength += tag.encode(os);
-			}
+    public void setScellsProp(ScellsProp scellsProp) {
+        this.scellsProp = scellsProp;
+    }
 
-			return codeLength;
-		}
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
 
-		public int decode(InputStream is) throws IOException {
-			return decode(is, true);
-		}
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
 
-		public int decode(InputStream is, boolean withTag) throws IOException {
-			int codeLength = 0;
-			int subCodeLength = 0;
-			if (withTag) {
-				codeLength += tag.decodeAndCheck(is);
-			}
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
 
-			BerLength length = new BerLength();
-			codeLength += length.decode(is);
-			int totalLength = length.val;
+        int codeLength = 0;
+        codeLength += scellsProp.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+        os.write(0xA2);
+        codeLength += 1;
 
-			while (subCodeLength < totalLength) {
-				PropScell element = new PropScell();
-				subCodeLength += element.decode(is, true);
-				seqOf.add(element);
-			}
-			if (subCodeLength != totalLength) {
-				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
 
-			}
-			codeLength += subCodeLength;
+        codeLength += crnti.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
 
-			return codeLength;
-		}
+        codeLength += BerLength.encodeLength(os, codeLength);
 
-		public void encodeAndSave(int encodingSizeGuess) throws IOException {
-			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
-			encode(os, false);
-			code = os.getArray();
-		}
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
 
-		public String toString() {
-			StringBuilder sb = new StringBuilder();
-			appendAsString(sb, 0);
-			return sb.toString();
-		}
+        return codeLength;
 
-		public void appendAsString(StringBuilder sb, int indentLevel) {
+    }
 
-			sb.append("[\n");
-			for (int i = 0; i < indentLevel + 1; i++) {
-				sb.append("\t");
-			}
-			if (seqOf == null) {
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            crnti = new CRNTI();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+            scellsProp = new ScellsProp();
+            subCodeLength += scellsProp.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crnti != null) {
+            sb.append("\"crnti\": ").append(crnti);
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("\"ecgi\": ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (scellsProp != null) {
+            sb.append("\"scellsProp\": ");
+            scellsProp.appendAsString(sb, indentLevel + 1);
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    public static class ScellsProp implements Serializable {
+
+        public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+        private static final long serialVersionUID = 1L;
+        public byte[] code = null;
+        private List<PropScell> seqOf = null;
+
+        public ScellsProp() {
+            seqOf = new ArrayList<PropScell>();
+        }
+
+        public ScellsProp(byte[] code) {
+            this.code = code;
+        }
+
+        public List<PropScell> getPropScell() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<PropScell>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                PropScell element = new PropScell();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("[\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
 //				sb.append("null");
-			}
-			else {
-				Iterator<PropScell> it = seqOf.iterator();
-				if (it.hasNext()) {
-					it.next().appendAsString(sb, indentLevel + 1);
-					while (it.hasNext()) {
-						sb.append(",\n");
-						for (int i = 0; i < indentLevel + 1; i++) {
-							sb.append("\t");
-						}
-						it.next().appendAsString(sb, indentLevel + 1);
-					}
-				}
-			}
+            } else {
+                Iterator<PropScell> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    it.next().appendAsString(sb, indentLevel + 1);
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        it.next().appendAsString(sb, indentLevel + 1);
+                    }
+                }
+            }
 
-			sb.append("\n");
-			for (int i = 0; i < indentLevel; i++) {
-				sb.append("\t");
-			}
-			sb.append("]");
-		}
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("]");
+        }
 
-	}
-
-	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
-
-	public byte[] code = null;
-	private CRNTI crnti = null;
-	private ECGI ecgi = null;
-	private ScellsProp scellsProp = null;
-	
-	public ScellAdd() {
-	}
-
-	public ScellAdd(byte[] code) {
-		this.code = code;
-	}
-
-	public void setCrnti(CRNTI crnti) {
-		this.crnti = crnti;
-	}
-
-	public CRNTI getCrnti() {
-		return crnti;
-	}
-
-	public void setEcgi(ECGI ecgi) {
-		this.ecgi = ecgi;
-	}
-
-	public ECGI getEcgi() {
-		return ecgi;
-	}
-
-	public void setScellsProp(ScellsProp scellsProp) {
-		this.scellsProp = scellsProp;
-	}
-
-	public ScellsProp getScellsProp() {
-		return scellsProp;
-	}
-
-	public int encode(BerByteArrayOutputStream os) throws IOException {
-		return encode(os, true);
-	}
-
-	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
-
-		if (code != null) {
-			for (int i = code.length - 1; i >= 0; i--) {
-				os.write(code[i]);
-			}
-			if (withTag) {
-				return tag.encode(os) + code.length;
-			}
-			return code.length;
-		}
-
-		int codeLength = 0;
-		codeLength += scellsProp.encode(os, false);
-		// write tag: CONTEXT_CLASS, CONSTRUCTED, 2
-		os.write(0xA2);
-		codeLength += 1;
-		
-		codeLength += ecgi.encode(os, false);
-		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
-		os.write(0xA1);
-		codeLength += 1;
-		
-		codeLength += crnti.encode(os, false);
-		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
-		os.write(0x80);
-		codeLength += 1;
-		
-		codeLength += BerLength.encodeLength(os, codeLength);
-
-		if (withTag) {
-			codeLength += tag.encode(os);
-		}
-
-		return codeLength;
-
-	}
-
-	public int decode(InputStream is) throws IOException {
-		return decode(is, true);
-	}
-
-	public int decode(InputStream is, boolean withTag) throws IOException {
-		int codeLength = 0;
-		int subCodeLength = 0;
-		BerTag berTag = new BerTag();
-
-		if (withTag) {
-			codeLength += tag.decodeAndCheck(is);
-		}
-
-		BerLength length = new BerLength();
-		codeLength += length.decode(is);
-
-		int totalLength = length.val;
-		codeLength += totalLength;
-
-		subCodeLength += berTag.decode(is);
-		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
-			crnti = new CRNTI();
-			subCodeLength += crnti.decode(is, false);
-			subCodeLength += berTag.decode(is);
-		}
-		else {
-			throw new IOException("Tag does not match the mandatory sequence element tag.");
-		}
-		
-		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
-			ecgi = new ECGI();
-			subCodeLength += ecgi.decode(is, false);
-			subCodeLength += berTag.decode(is);
-		}
-		else {
-			throw new IOException("Tag does not match the mandatory sequence element tag.");
-		}
-		
-		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
-			scellsProp = new ScellsProp();
-			subCodeLength += scellsProp.decode(is, false);
-			if (subCodeLength == totalLength) {
-				return codeLength;
-			}
-		}
-		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
-
-		
-	}
-
-	public void encodeAndSave(int encodingSizeGuess) throws IOException {
-		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
-		encode(os, false);
-		code = os.getArray();
-	}
-
-	public String toString() {
-		StringBuilder sb = new StringBuilder();
-		appendAsString(sb, 0);
-		return sb.toString();
-	}
-
-	public void appendAsString(StringBuilder sb, int indentLevel) {
-
-		sb.append("{");
-		sb.append("\n");
-		for (int i = 0; i < indentLevel + 1; i++) {
-			sb.append("\t");
-		}
-		if (crnti != null) {
-			sb.append("\"crnti\": ").append(crnti);
-		}
-		
-		sb.append(",\n");
-		for (int i = 0; i < indentLevel + 1; i++) {
-			sb.append("\t");
-		}
-		if (ecgi != null) {
-			sb.append("\"ecgi\": ");
-			ecgi.appendAsString(sb, indentLevel + 1);
-		}
-		
-		sb.append(",\n");
-		for (int i = 0; i < indentLevel + 1; i++) {
-			sb.append("\t");
-		}
-		if (scellsProp != null) {
-			sb.append("\"scellsProp\": ");
-			scellsProp.appendAsString(sb, indentLevel + 1);
-		}
-		
-		sb.append("\n");
-		for (int i = 0; i < indentLevel; i++) {
-			sb.append("\t");
-		}
-		sb.append("}");
-	}
+        public void addPropScell(PropScell propScell) {
+            seqOf.add(propScell);
+        }
+    }
 
 }
 
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/ScellDelete.java b/src/main/java/org.onosproject.xran/codecs/pdu/ScellDelete.java
index 278c7f6..02dd7d2 100644
--- a/src/main/java/org.onosproject.xran/codecs/pdu/ScellDelete.java
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/ScellDelete.java
@@ -10,321 +10,349 @@
 import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
 import org.openmuc.jasn1.ber.BerLength;
 import org.openmuc.jasn1.ber.BerTag;
+import org.openmuc.jasn1.ber.types.string.BerUTF8String;
 
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
 public class ScellDelete implements Serializable {
 
-	private static final long serialVersionUID = 1L;
+    public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+    private static final long serialVersionUID = 1L;
+    public byte[] code = null;
+    private CRNTI crnti = null;
+    private ECGI ecgi = null;
+    private ScellsInd scellsInd = null;
+    public ScellDelete() {
+    }
+    public ScellDelete(byte[] code) {
+        this.code = code;
+    }
 
-	public static class ScellsInd implements Serializable {
+    public static XrancPdu constructPacket(ECGI ecgi, CRNTI crnti, PCIARFCN pciarfcn) {
+        ScellDelete scellDelete = new ScellDelete();
+        scellDelete.setEcgi(ecgi);
+        scellDelete.setCrnti(crnti);
+        ScellsInd scellsInd = new ScellsInd();
+        scellsInd.addPCIARFCN(pciarfcn);
+        scellDelete.setScellsInd(scellsInd);
 
-		private static final long serialVersionUID = 1L;
+        BerUTF8String ver = null;
+        try {
+            ver = new BerUTF8String("3");
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
 
-		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
-		public byte[] code = null;
-		private List<PCIARFCN> seqOf = null;
+        XrancApiID apiID = new XrancApiID(28);
+        XrancPduBody body = new XrancPduBody();
+        body.setScellDelete(scellDelete);
 
-		public ScellsInd() {
-			seqOf = new ArrayList<PCIARFCN>();
-		}
+        XrancPduHdr hdr = new XrancPduHdr();
+        hdr.setVer(ver);
+        hdr.setApiId(apiID);
 
-		public ScellsInd(byte[] code) {
-			this.code = code;
-		}
+        XrancPdu pdu = new XrancPdu();
+        pdu.setBody(body);
+        pdu.setHdr(hdr);
 
-		public List<PCIARFCN> getPCIARFCN() {
-			if (seqOf == null) {
-				seqOf = new ArrayList<PCIARFCN>();
-			}
-			return seqOf;
-		}
+        return pdu;
 
-		public int encode(BerByteArrayOutputStream os) throws IOException {
-			return encode(os, true);
-		}
+    }
 
-		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+    public CRNTI getCrnti() {
+        return crnti;
+    }
 
-			if (code != null) {
-				for (int i = code.length - 1; i >= 0; i--) {
-					os.write(code[i]);
-				}
-				if (withTag) {
-					return tag.encode(os) + code.length;
-				}
-				return code.length;
-			}
+    public void setCrnti(CRNTI crnti) {
+        this.crnti = crnti;
+    }
 
-			int codeLength = 0;
-			for (int i = (seqOf.size() - 1); i >= 0; i--) {
-				codeLength += seqOf.get(i).encode(os, true);
-			}
+    public ECGI getEcgi() {
+        return ecgi;
+    }
 
-			codeLength += BerLength.encodeLength(os, codeLength);
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
 
-			if (withTag) {
-				codeLength += tag.encode(os);
-			}
+    public ScellsInd getScellsInd() {
+        return scellsInd;
+    }
 
-			return codeLength;
-		}
+    public void setScellsInd(ScellsInd scellsInd) {
+        this.scellsInd = scellsInd;
+    }
 
-		public int decode(InputStream is) throws IOException {
-			return decode(is, true);
-		}
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
 
-		public int decode(InputStream is, boolean withTag) throws IOException {
-			int codeLength = 0;
-			int subCodeLength = 0;
-			if (withTag) {
-				codeLength += tag.decodeAndCheck(is);
-			}
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
 
-			BerLength length = new BerLength();
-			codeLength += length.decode(is);
-			int totalLength = length.val;
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
 
-			while (subCodeLength < totalLength) {
-				PCIARFCN element = new PCIARFCN();
-				subCodeLength += element.decode(is, true);
-				seqOf.add(element);
-			}
-			if (subCodeLength != totalLength) {
-				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+        int codeLength = 0;
+        codeLength += scellsInd.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+        os.write(0xA2);
+        codeLength += 1;
 
-			}
-			codeLength += subCodeLength;
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
 
-			return codeLength;
-		}
+        codeLength += crnti.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
 
-		public void encodeAndSave(int encodingSizeGuess) throws IOException {
-			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
-			encode(os, false);
-			code = os.getArray();
-		}
+        codeLength += BerLength.encodeLength(os, codeLength);
 
-		public String toString() {
-			StringBuilder sb = new StringBuilder();
-			appendAsString(sb, 0);
-			return sb.toString();
-		}
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
 
-		public void appendAsString(StringBuilder sb, int indentLevel) {
+        return codeLength;
 
-			sb.append("[\n");
-			for (int i = 0; i < indentLevel + 1; i++) {
-				sb.append("\t");
-			}
-			if (seqOf == null) {
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            crnti = new CRNTI();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+            scellsInd = new ScellsInd();
+            subCodeLength += scellsInd.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crnti != null) {
+            sb.append("\"crnti\": ").append(crnti);
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("\"ecgi\": ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (scellsInd != null) {
+            sb.append("\"scellsInd\": ");
+            scellsInd.appendAsString(sb, indentLevel + 1);
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    public static class ScellsInd implements Serializable {
+
+        public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+        private static final long serialVersionUID = 1L;
+        public byte[] code = null;
+        private List<PCIARFCN> seqOf = null;
+
+        public ScellsInd() {
+            seqOf = new ArrayList<PCIARFCN>();
+        }
+
+        public ScellsInd(byte[] code) {
+            this.code = code;
+        }
+
+        public List<PCIARFCN> getPCIARFCN() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<PCIARFCN>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                PCIARFCN element = new PCIARFCN();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("[\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
 //				sb.append("null");
-			}
-			else {
-				Iterator<PCIARFCN> it = seqOf.iterator();
-				if (it.hasNext()) {
-					it.next().appendAsString(sb, indentLevel + 1);
-					while (it.hasNext()) {
-						sb.append(",\n");
-						for (int i = 0; i < indentLevel + 1; i++) {
-							sb.append("\t");
-						}
-						it.next().appendAsString(sb, indentLevel + 1);
-					}
-				}
-			}
+            } else {
+                Iterator<PCIARFCN> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    it.next().appendAsString(sb, indentLevel + 1);
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        it.next().appendAsString(sb, indentLevel + 1);
+                    }
+                }
+            }
 
-			sb.append("\n");
-			for (int i = 0; i < indentLevel; i++) {
-				sb.append("\t");
-			}
-			sb.append("]");
-		}
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("]");
+        }
 
-	}
-
-	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
-
-	public byte[] code = null;
-	private CRNTI crnti = null;
-	private ECGI ecgi = null;
-	private ScellsInd scellsInd = null;
-	
-	public ScellDelete() {
-	}
-
-	public ScellDelete(byte[] code) {
-		this.code = code;
-	}
-
-	public void setCrnti(CRNTI crnti) {
-		this.crnti = crnti;
-	}
-
-	public CRNTI getCrnti() {
-		return crnti;
-	}
-
-	public void setEcgi(ECGI ecgi) {
-		this.ecgi = ecgi;
-	}
-
-	public ECGI getEcgi() {
-		return ecgi;
-	}
-
-	public void setScellsInd(ScellsInd scellsInd) {
-		this.scellsInd = scellsInd;
-	}
-
-	public ScellsInd getScellsInd() {
-		return scellsInd;
-	}
-
-	public int encode(BerByteArrayOutputStream os) throws IOException {
-		return encode(os, true);
-	}
-
-	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
-
-		if (code != null) {
-			for (int i = code.length - 1; i >= 0; i--) {
-				os.write(code[i]);
-			}
-			if (withTag) {
-				return tag.encode(os) + code.length;
-			}
-			return code.length;
-		}
-
-		int codeLength = 0;
-		codeLength += scellsInd.encode(os, false);
-		// write tag: CONTEXT_CLASS, CONSTRUCTED, 2
-		os.write(0xA2);
-		codeLength += 1;
-		
-		codeLength += ecgi.encode(os, false);
-		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
-		os.write(0xA1);
-		codeLength += 1;
-		
-		codeLength += crnti.encode(os, false);
-		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
-		os.write(0x80);
-		codeLength += 1;
-		
-		codeLength += BerLength.encodeLength(os, codeLength);
-
-		if (withTag) {
-			codeLength += tag.encode(os);
-		}
-
-		return codeLength;
-
-	}
-
-	public int decode(InputStream is) throws IOException {
-		return decode(is, true);
-	}
-
-	public int decode(InputStream is, boolean withTag) throws IOException {
-		int codeLength = 0;
-		int subCodeLength = 0;
-		BerTag berTag = new BerTag();
-
-		if (withTag) {
-			codeLength += tag.decodeAndCheck(is);
-		}
-
-		BerLength length = new BerLength();
-		codeLength += length.decode(is);
-
-		int totalLength = length.val;
-		codeLength += totalLength;
-
-		subCodeLength += berTag.decode(is);
-		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
-			crnti = new CRNTI();
-			subCodeLength += crnti.decode(is, false);
-			subCodeLength += berTag.decode(is);
-		}
-		else {
-			throw new IOException("Tag does not match the mandatory sequence element tag.");
-		}
-		
-		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
-			ecgi = new ECGI();
-			subCodeLength += ecgi.decode(is, false);
-			subCodeLength += berTag.decode(is);
-		}
-		else {
-			throw new IOException("Tag does not match the mandatory sequence element tag.");
-		}
-		
-		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
-			scellsInd = new ScellsInd();
-			subCodeLength += scellsInd.decode(is, false);
-			if (subCodeLength == totalLength) {
-				return codeLength;
-			}
-		}
-		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
-
-		
-	}
-
-	public void encodeAndSave(int encodingSizeGuess) throws IOException {
-		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
-		encode(os, false);
-		code = os.getArray();
-	}
-
-	public String toString() {
-		StringBuilder sb = new StringBuilder();
-		appendAsString(sb, 0);
-		return sb.toString();
-	}
-
-	public void appendAsString(StringBuilder sb, int indentLevel) {
-
-		sb.append("{");
-		sb.append("\n");
-		for (int i = 0; i < indentLevel + 1; i++) {
-			sb.append("\t");
-		}
-		if (crnti != null) {
-			sb.append("\"crnti\": ").append(crnti);
-		}
-		
-		sb.append(",\n");
-		for (int i = 0; i < indentLevel + 1; i++) {
-			sb.append("\t");
-		}
-		if (ecgi != null) {
-			sb.append("\"ecgi\": ");
-			ecgi.appendAsString(sb, indentLevel + 1);
-		}
-		
-		sb.append(",\n");
-		for (int i = 0; i < indentLevel + 1; i++) {
-			sb.append("\t");
-		}
-		if (scellsInd != null) {
-			sb.append("\"scellsInd\": ");
-			scellsInd.appendAsString(sb, indentLevel + 1);
-		}
-		
-		sb.append("\n");
-		for (int i = 0; i < indentLevel; i++) {
-			sb.append("\t");
-		}
-		sb.append("}");
-	}
+        public void addPCIARFCN(PCIARFCN pciarfcn) {
+            seqOf.add(pciarfcn);
+        }
+    }
 
 }
 
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/XICICConfig.java b/src/main/java/org.onosproject.xran/codecs/pdu/XICICConfig.java
index 6efe465..60be502 100644
--- a/src/main/java/org.onosproject.xran/codecs/pdu/XICICConfig.java
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/XICICConfig.java
@@ -37,7 +37,7 @@
 	private BerInteger startPrbUl = null;
 	private BerInteger endPrbUl = null;
 	private BerBitString subframeBitmaskUl = null;
-	
+
 	public XICICConfig() {
 	}
 
@@ -150,61 +150,79 @@
 		}
 
 		int codeLength = 0;
-		codeLength += subframeBitmaskUl.encode(os, false);
-		// write tag: CONTEXT_CLASS, PRIMITIVE, 10
-		os.write(0x8A);
-		codeLength += 1;
-		
-		codeLength += endPrbUl.encode(os, false);
-		// write tag: CONTEXT_CLASS, PRIMITIVE, 9
-		os.write(0x89);
-		codeLength += 1;
-		
-		codeLength += startPrbUl.encode(os, false);
-		// write tag: CONTEXT_CLASS, PRIMITIVE, 8
-		os.write(0x88);
-		codeLength += 1;
-		
-		codeLength += p0UePusch.encode(os, false);
-		// write tag: CONTEXT_CLASS, PRIMITIVE, 7
-		os.write(0x87);
-		codeLength += 1;
-		
-		codeLength += subframeBitmaskDl.encode(os, false);
-		// write tag: CONTEXT_CLASS, PRIMITIVE, 6
-		os.write(0x86);
-		codeLength += 1;
-		
-		codeLength += endPrbDl.encode(os, false);
-		// write tag: CONTEXT_CLASS, PRIMITIVE, 5
-		os.write(0x85);
-		codeLength += 1;
-		
-		codeLength += startPrbDl.encode(os, false);
-		// write tag: CONTEXT_CLASS, PRIMITIVE, 4
-		os.write(0x84);
-		codeLength += 1;
-		
-		codeLength += pa.encode(os, false);
-		// write tag: CONTEXT_CLASS, PRIMITIVE, 3
-		os.write(0x83);
-		codeLength += 1;
-		
+		if (subframeBitmaskUl != null) {
+			codeLength += subframeBitmaskUl.encode(os, false);
+			// write tag: CONTEXT_CLASS, PRIMITIVE, 10
+			os.write(0x8A);
+			codeLength += 1;
+		}
+
+		if (endPrbUl != null) {
+			codeLength += endPrbUl.encode(os, false);
+			// write tag: CONTEXT_CLASS, PRIMITIVE, 9
+			os.write(0x89);
+			codeLength += 1;
+		}
+
+		if (startPrbUl != null) {
+			codeLength += startPrbUl.encode(os, false);
+			// write tag: CONTEXT_CLASS, PRIMITIVE, 8
+			os.write(0x88);
+			codeLength += 1;
+		}
+
+		if (p0UePusch != null) {
+			codeLength += p0UePusch.encode(os, false);
+			// write tag: CONTEXT_CLASS, PRIMITIVE, 7
+			os.write(0x87);
+			codeLength += 1;
+		}
+
+		if (subframeBitmaskDl != null) {
+			codeLength += subframeBitmaskDl.encode(os, false);
+			// write tag: CONTEXT_CLASS, PRIMITIVE, 6
+			os.write(0x86);
+			codeLength += 1;
+		}
+
+		if (endPrbDl != null) {
+			codeLength += endPrbDl.encode(os, false);
+			// write tag: CONTEXT_CLASS, PRIMITIVE, 5
+			os.write(0x85);
+			codeLength += 1;
+		}
+
+		if (startPrbDl != null) {
+			codeLength += startPrbDl.encode(os, false);
+			// write tag: CONTEXT_CLASS, PRIMITIVE, 4
+			os.write(0x84);
+			codeLength += 1;
+		}
+
+		if (pa != null) {
+			codeLength += pa.encode(os, false);
+			// write tag: CONTEXT_CLASS, PRIMITIVE, 3
+			os.write(0x83);
+			codeLength += 1;
+		}
+
 		codeLength += crnti.encode(os, false);
 		// write tag: CONTEXT_CLASS, PRIMITIVE, 2
 		os.write(0x82);
 		codeLength += 1;
-		
-		codeLength += pciArfcn.encode(os, false);
-		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
-		os.write(0xA1);
-		codeLength += 1;
-		
+
+		if (pciArfcn != null) {
+			codeLength += pciArfcn.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+			os.write(0xA1);
+			codeLength += 1;
+		}
+
 		codeLength += ecgi.encode(os, false);
 		// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
 		os.write(0xA0);
 		codeLength += 1;
-		
+
 		codeLength += BerLength.encodeLength(os, codeLength);
 
 		if (withTag) {
@@ -243,88 +261,88 @@
 		else {
 			throw new IOException("Tag does not match the mandatory sequence element tag.");
 		}
-		
+
 		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
 			pciArfcn = new PCIARFCN();
 			subCodeLength += pciArfcn.decode(is, false);
 			subCodeLength += berTag.decode(is);
 		}
-		else {
-			throw new IOException("Tag does not match the mandatory sequence element tag.");
-		}
-		
+
 		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
 			crnti = new CRNTI();
 			subCodeLength += crnti.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
 			subCodeLength += berTag.decode(is);
 		}
 		else {
 			throw new IOException("Tag does not match the mandatory sequence element tag.");
 		}
-		
+
 		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 3)) {
 			pa = new XICICPA();
 			subCodeLength += pa.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
 			subCodeLength += berTag.decode(is);
 		}
-		else {
-			throw new IOException("Tag does not match the mandatory sequence element tag.");
-		}
-		
+
 		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 4)) {
 			startPrbDl = new BerInteger();
 			subCodeLength += startPrbDl.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
 			subCodeLength += berTag.decode(is);
 		}
-		else {
-			throw new IOException("Tag does not match the mandatory sequence element tag.");
-		}
-		
+
 		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 5)) {
 			endPrbDl = new BerInteger();
 			subCodeLength += endPrbDl.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
 			subCodeLength += berTag.decode(is);
 		}
-		else {
-			throw new IOException("Tag does not match the mandatory sequence element tag.");
-		}
-		
+
 		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 6)) {
 			subframeBitmaskDl = new BerBitString();
 			subCodeLength += subframeBitmaskDl.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
 			subCodeLength += berTag.decode(is);
 		}
-		else {
-			throw new IOException("Tag does not match the mandatory sequence element tag.");
-		}
-		
+
 		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 7)) {
 			p0UePusch = new BerInteger();
 			subCodeLength += p0UePusch.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
 			subCodeLength += berTag.decode(is);
 		}
-		else {
-			throw new IOException("Tag does not match the mandatory sequence element tag.");
-		}
-		
+
 		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 8)) {
 			startPrbUl = new BerInteger();
 			subCodeLength += startPrbUl.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
 			subCodeLength += berTag.decode(is);
 		}
-		else {
-			throw new IOException("Tag does not match the mandatory sequence element tag.");
-		}
-		
+
 		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 9)) {
 			endPrbUl = new BerInteger();
 			subCodeLength += endPrbUl.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
 			subCodeLength += berTag.decode(is);
 		}
-		else {
-			throw new IOException("Tag does not match the mandatory sequence element tag.");
-		}
-		
+
 		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 10)) {
 			subframeBitmaskUl = new BerBitString();
 			subCodeLength += subframeBitmaskUl.decode(is, false);
@@ -334,7 +352,7 @@
 		}
 		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
 
-		
+
 	}
 
 	public void encodeAndSave(int encodingSizeGuess) throws IOException {
