implemented PATCH, HO, SCELLADD, XICIC
diff --git a/src/main/java/org.onosproject.xran/XranStore.java b/src/main/java/org.onosproject.xran/XranStore.java
index 349e8f5..081f51e 100644
--- a/src/main/java/org.onosproject.xran/XranStore.java
+++ b/src/main/java/org.onosproject.xran/XranStore.java
@@ -47,8 +47,6 @@
 
     RnibLink getLinkBetweenCellIdUeId(String cellId, long euId);
 
-    boolean createLinkBetweenCellIdUeId(String cellId, long euId, String type);
-
     RnibLink getLink(ECGI ecgi, MMEUES1APID mme);
 
     void modifyLinkRrmConf(RnibLink link, JsonNode rrmConf);
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 {
diff --git a/src/main/java/org.onosproject.xran/controller/XranController.java b/src/main/java/org.onosproject.xran/controller/XranController.java
index 42ca41e..02f8378 100644
--- a/src/main/java/org.onosproject.xran/controller/XranController.java
+++ b/src/main/java/org.onosproject.xran/controller/XranController.java
@@ -39,4 +39,8 @@
     void removeListener(XranHostListener listener);
 
     SynchronousQueue<String> sendModifiedRRMConf(RRMConfig rrmConfig, boolean xICIC);
+
+    SynchronousQueue<String> sendScellAdd(RnibLink link);
+
+    boolean sendScellDelete(RnibLink link);
 }
diff --git a/src/main/java/org.onosproject.xran/controller/XranControllerImpl.java b/src/main/java/org.onosproject.xran/controller/XranControllerImpl.java
index a5e073a..1d9653d 100644
--- a/src/main/java/org.onosproject.xran/controller/XranControllerImpl.java
+++ b/src/main/java/org.onosproject.xran/controller/XranControllerImpl.java
@@ -107,8 +107,10 @@
     private LinkMap linkMap;
     /* MAPS */
     private ConcurrentMap<String, ECGI> legitCells = new ConcurrentHashMap<>();
-    private ConcurrentMap<CRNTI, SynchronousQueue<String>> hoQueue = new ConcurrentHashMap<CRNTI, SynchronousQueue<String>>();
-    private ConcurrentMap<ECGI, SynchronousQueue<String>> RRMCellQueue = new ConcurrentHashMap<ECGI, SynchronousQueue<String>>();
+    private ConcurrentMap<CRNTI, SynchronousQueue<String>> hoQueue = new ConcurrentHashMap<>();
+    private ConcurrentMap<ECGI, SynchronousQueue<String>> RRMCellQueue = new ConcurrentHashMap<>();
+    private ConcurrentMap<CRNTI, SynchronousQueue<String>> scellAddQueue = new ConcurrentHashMap<>();
+    private ConcurrentMap<CRNTI, SynchronousQueue<String>> scellDeleteQueue = new ConcurrentHashMap<>();
     /* AGENTS */
     private InternalXranDeviceAgent deviceAgent = new InternalXranDeviceAgent();
     private InternalXranHostAgent hostAgent = new InternalXranHostAgent();
@@ -215,6 +217,70 @@
         return queue;
     }
 
+    @Override
+    public SynchronousQueue<String> sendScellAdd(RnibLink link) {
+        RnibCell secondaryCell = link.getLinkId().getCell(),
+                primaryCell = linkMap.getPrimaryCell(link.getLinkId().getUe());
+        ECGI primaryEcgi = primaryCell.getEcgi();
+        ChannelHandlerContext ctx = cellMap.getCtx(primaryEcgi);
+
+        CRNTI crnti = linkMap.getCrnti(link.getLinkId().getMmeues1apid());
+
+        CellConfigReport cellReport = secondaryCell.getConf();
+
+        if (cellReport != null) {
+            PCIARFCN pciarfcn = new PCIARFCN();
+            pciarfcn.setPci(cellReport.getPci());
+            pciarfcn.setEarfcnDl(cellReport.getEarfcnDl());
+
+            PropScell propScell = new PropScell();
+            propScell.setPciArfcn(pciarfcn);
+
+            XrancPdu pdu = ScellAdd.constructPacket(primaryEcgi, crnti, propScell);
+            try {
+                ctx.writeAndFlush(getSctpMessage(pdu));
+                SynchronousQueue<String> queue = new SynchronousQueue<>();
+                scellAddQueue.put(crnti, queue);
+
+                return queue;
+            } catch (IOException e) {
+                log.error(ExceptionUtils.getFullStackTrace(e));
+                e.printStackTrace();
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public boolean sendScellDelete(RnibLink link) {
+        RnibCell secondaryCell = link.getLinkId().getCell(),
+                primaryCell = linkMap.getPrimaryCell(link.getLinkId().getUe());
+        ECGI primaryEcgi = primaryCell.getEcgi();
+        ChannelHandlerContext ctx = cellMap.getCtx(primaryEcgi);
+
+        CRNTI crnti = linkMap.getCrnti(link.getLinkId().getMmeues1apid());
+
+        CellConfigReport cellReport = secondaryCell.getConf();
+
+        if (cellReport != null) {
+            PCIARFCN pciarfcn = new PCIARFCN();
+            pciarfcn.setPci(cellReport.getPci());
+            pciarfcn.setEarfcnDl(cellReport.getEarfcnDl());
+
+            XrancPdu pdu = ScellDelete.constructPacket(primaryEcgi, crnti, pciarfcn);
+
+            try {
+                ctx.writeAndFlush(getSctpMessage(pdu));
+                link.setType(RnibLink.Type.NON_SERVING);
+                return true;
+            } catch (IOException e) {
+                log.error(ExceptionUtils.getFullStackTrace(e));
+                e.printStackTrace();
+            }
+        }
+        return false;
+    }
+
     private void restartTimer(RnibUe ue) {
         Timer timer = new Timer();
         ue.setTimer(timer);
@@ -319,7 +385,7 @@
                 case HOST_MOVED: {
                     RnibUe ue = ueMap.get(hostIdtoMME(event.subject().id()));
                     if (ue != null) {
-                        ECGI ecgi_primary = linkMap.getPrimaryCell(ue);
+                        ECGI ecgi_primary = linkMap.getPrimaryCell(ue).getEcgi();
                         RnibCell primary = cellMap.get(ecgi_primary);
                         ue.setMeasConfig(null);
                         if (primary != null) {
@@ -797,7 +863,32 @@
                     ctx.writeAndFlush(getSctpMessage(xrancPdu));
                     break;
                 }
-                // TODO: Case 26: ScellAdd 27: ScellAddStatus 28: ScellDelete
+                case 27: {
+                    //Decode ScellAddStatus
+                    ScellAddStatus scellAddStatus = recv_pdu.getBody().getScellAddStatus();
+                    try {
+                        scellAddQueue.get(scellAddStatus.getCrnti()).put("Scell's status: " + scellAddStatus.getStatus());
+                        if (scellAddStatus.getStatus().getBerEnum().get(0).value.intValue() == 0) {
+
+                            scellAddStatus.getScellsInd().getPCIARFCN().forEach(
+                                    pciarfcn -> {
+                                        RnibCell cell = cellMap.get(pciarfcn);
+                                        RnibLink link = linkMap.get(cell.getEcgi(), scellAddStatus.getCrnti());
+                                        link.setType(RnibLink.Type.SERVING_SECONDARY_CA);
+                                    }
+                            );
+                        } else {
+                            log.error("Scell addition failed.");
+                        }
+                    } catch (InterruptedException e) {
+                        log.error(ExceptionUtils.getFullStackTrace(e));
+                        e.printStackTrace();
+                    } finally {
+                        scellAddQueue.remove(scellAddStatus.getCrnti());
+                    }
+                    break;
+                }
+                // TODO: 28: ScellDelete
 
                 case 30: {
                     // Decode RRMConfig Status
diff --git a/src/main/java/org.onosproject.xran/entities/RnibCell.java b/src/main/java/org.onosproject.xran/entities/RnibCell.java
index 81aeafd..e56b6b1 100644
--- a/src/main/java/org.onosproject.xran/entities/RnibCell.java
+++ b/src/main/java/org.onosproject.xran/entities/RnibCell.java
@@ -55,8 +55,10 @@
 
     public RnibCell() {
         prbUsage = new PrbUsageContainer();
-        setDefaultRRMConf();
         version = "3";
+
+        rrmConfig = new RRMConfig();
+        rrmConfig.setEcgi(ecgi);
     }
 
     public static URI uri(ECGI ecgi) {
@@ -109,45 +111,6 @@
         this.prbUsage = prbUsage;
     }
 
-    private void setDefaultRRMConf() {
-        rrmConfig = new RRMConfig();
-
-        rrmConfig.setEcgi(ecgi);
-
-        RRMConfig.StartPrbDl startPrbDl = new RRMConfig.StartPrbDl();
-        startPrbDl.addBerInteger(new BerInteger(0));
-        startPrbDl.addBerInteger(new BerInteger(50));
-
-        rrmConfig.setStartPrbDl(startPrbDl);
-
-        RRMConfig.StartPrbUl startPrbUl = new RRMConfig.StartPrbUl();
-        startPrbUl.addBerInteger(new BerInteger(50));
-        startPrbUl.addBerInteger(new BerInteger(100));
-
-        rrmConfig.setStartPrbUl(startPrbUl);
-
-        RRMConfig.EndPrbDl endPrbDl = new RRMConfig.EndPrbDl();
-        endPrbDl.addBerInteger(new BerInteger(50));
-        endPrbDl.addBerInteger(new BerInteger(100));
-
-        rrmConfig.setEndPrbDl(endPrbDl);
-
-        RRMConfig.EndPrbUl endPrbUl = new RRMConfig.EndPrbUl();
-        endPrbUl.addBerInteger(new BerInteger(50));
-        endPrbUl.addBerInteger(new BerInteger(100));
-
-        rrmConfig.setEndPrbUl(endPrbUl);
-
-        RRMConfig.SubframeBitmaskDl subframeBitmaskDl = new RRMConfig.SubframeBitmaskDl();
-        BerBitString berBitString = new BerBitString(new byte[]{(byte) 0xAA, (byte) 0x80}, 10);
-        BerBitString berBitString1 = new BerBitString(new byte[]{(byte) 0x55, (byte) 0x40}, 10);
-
-        subframeBitmaskDl.addBerBitString(berBitString);
-        subframeBitmaskDl.addBerBitString(berBitString1);
-
-        rrmConfig.setSubframeBitmaskDl(subframeBitmaskDl);
-    }
-
     public ECGI getEcgi() {
         return ecgi;
     }
@@ -177,7 +140,7 @@
             if (start_prb_dl != null) {
                 RRMConfig.StartPrbDl startPrbDl = new RRMConfig.StartPrbDl();
                 if (start_prb_dl.isArray()) {
-                    if (rrmConfig.getStartPrbDl().getSeqOf().size() == start_prb_dl.size()) {
+                    if (ueList.size() == start_prb_dl.size()) {
                         List<BerInteger> collect = Stream.of(start_prb_dl)
                                 .map(val -> new BerInteger(val.asInt()))
                                 .collect(Collectors.toList());
@@ -193,7 +156,7 @@
             if (end_prb_dl != null) {
                 RRMConfig.EndPrbDl endPrbDl = new RRMConfig.EndPrbDl();
                 if (end_prb_dl.isArray()) {
-                    if (rrmConfig.getEndPrbDl().getSeqOf().size() == end_prb_dl.size()) {
+                    if (ueList.size() == end_prb_dl.size()) {
                         List<BerInteger> collect = Stream.of(end_prb_dl)
                                 .map(val -> new BerInteger(val.asInt()))
                                 .collect(Collectors.toList());
@@ -209,7 +172,7 @@
             if (start_prb_ul != null) {
                 RRMConfig.StartPrbUl startPrbUl = new RRMConfig.StartPrbUl();
                 if (start_prb_ul.isArray()) {
-                    if (rrmConfig.getStartPrbUl().getSeqOf().size() == start_prb_ul.size()) {
+                    if (ueList.size() == start_prb_ul.size()) {
                         List<BerInteger> collect = Stream.of(start_prb_ul)
                                 .map(val -> new BerInteger(val.asInt()))
                                 .collect(Collectors.toList());
@@ -225,7 +188,7 @@
             if (end_prb_ul != null) {
                 RRMConfig.EndPrbUl endPrbUl = new RRMConfig.EndPrbUl();
                 if (end_prb_ul.isArray()) {
-                    if (rrmConfig.getEndPrbUl().getSeqOf().size() == end_prb_ul.size()) {
+                    if (ueList.size() == end_prb_ul.size()) {
                         List<BerInteger> collect = Stream.of(end_prb_ul)
                                 .map(val -> new BerInteger(val.asInt()))
                                 .collect(Collectors.toList());
@@ -237,8 +200,6 @@
         }
 
         rrmConfig.setCrnti(crnti);
-
-        // TODO
     }
 
     public SchedMeasReportPerCell.QciVals getQci() {
diff --git a/src/main/java/org.onosproject.xran/entities/RnibLink.java b/src/main/java/org.onosproject.xran/entities/RnibLink.java
index 8af1644..9b024b9 100644
--- a/src/main/java/org.onosproject.xran/entities/RnibLink.java
+++ b/src/main/java/org.onosproject.xran/entities/RnibLink.java
@@ -17,6 +17,7 @@
 package org.onosproject.xran.entities;
 
 import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.collect.Lists;
 import org.onosproject.xran.codecs.api.*;
 import org.onosproject.xran.codecs.pdu.PDCPMeasReportPerUe;
 import org.onosproject.xran.codecs.pdu.RRMConfig;
@@ -65,7 +66,11 @@
 
         linkId = LinkId.valueOf(cell, ue);
 
-        setDefaultRRMConf();
+        rrmParameters = new RRMConfig();
+        RRMConfig.Crnti crnti = new RRMConfig.Crnti();
+        crnti.addCRNTI(linkId.getUe().getRanId());
+        rrmParameters.setCrnti(crnti);
+        rrmParameters.setEcgi(linkId.getEcgi());
     }
 
     public Timer getTimer() {
@@ -133,70 +138,56 @@
 
     public void modifyRrmParameters(JsonNode rrmConfigNode) {
         {
-            JsonNode start_prb_dl = rrmConfigNode.get("start_prb_dl");
-            if (start_prb_dl != null) {
+            JsonNode start_prb_dl = rrmConfigNode.path("start_prb_dl");
+            if (!start_prb_dl.isMissingNode()) {
                 RRMConfig.StartPrbDl startPrbDl = new RRMConfig.StartPrbDl();
-                if (start_prb_dl.isArray()) {
-                    if (rrmParameters.getStartPrbDl().getSeqOf().size() == start_prb_dl.size()) {
-                        List<BerInteger> collect = Stream.of(start_prb_dl)
-                                .map(val -> new BerInteger(val.asInt()))
-                                .collect(Collectors.toList());
-                        startPrbDl.setSeqOf(collect);
-                    }
-                }
+
+                List<BerInteger> collect = Lists.newArrayList();
+                collect.add(new BerInteger(start_prb_dl.asInt()));
+                startPrbDl.setSeqOf(collect);
+
                 rrmParameters.setStartPrbDl(startPrbDl);
             }
         }
 
         {
             JsonNode end_prb_dl = rrmConfigNode.get("end_prb_dl");
-            if (end_prb_dl != null) {
+            if (!end_prb_dl.isMissingNode()) {
                 RRMConfig.EndPrbDl endPrbDl = new RRMConfig.EndPrbDl();
-                if (end_prb_dl.isArray()) {
-                    if (rrmParameters.getEndPrbDl().getSeqOf().size() == end_prb_dl.size()) {
-                        List<BerInteger> collect = Stream.of(end_prb_dl)
-                                .map(val -> new BerInteger(val.asInt()))
-                                .collect(Collectors.toList());
-                        endPrbDl.setSeqOf(collect);
-                    }
-                }
+
+                List<BerInteger> collect = Lists.newArrayList();
+                collect.add(new BerInteger(end_prb_dl.asInt()));
+                endPrbDl.setSeqOf(collect);
+
                 rrmParameters.setEndPrbDl(endPrbDl);
             }
         }
 
         {
             JsonNode start_prb_ul = rrmConfigNode.get("start_prb_ul");
-            if (start_prb_ul != null) {
+            if (!start_prb_ul.isMissingNode()) {
                 RRMConfig.StartPrbUl startPrbUl = new RRMConfig.StartPrbUl();
-                if (start_prb_ul.isArray()) {
-                    if (rrmParameters.getStartPrbUl().getSeqOf().size() == start_prb_ul.size()) {
-                        List<BerInteger> collect = Stream.of(start_prb_ul)
-                                .map(val -> new BerInteger(val.asInt()))
-                                .collect(Collectors.toList());
-                        startPrbUl.setSeqOf(collect);
-                    }
-                }
+
+                List<BerInteger> collect = Lists.newArrayList();
+                collect.add(new BerInteger(start_prb_ul.asInt()));
+                startPrbUl.setSeqOf(collect);
+
                 rrmParameters.setStartPrbUl(startPrbUl);
             }
         }
 
         {
             JsonNode end_prb_ul = rrmConfigNode.get("end_prb_ul");
-            if (end_prb_ul != null) {
+            if (!end_prb_ul.isMissingNode()) {
                 RRMConfig.EndPrbUl endPrbUl = new RRMConfig.EndPrbUl();
-                if (end_prb_ul.isArray()) {
-                    if (rrmParameters.getEndPrbUl().getSeqOf().size() == end_prb_ul.size()) {
-                        List<BerInteger> collect = Stream.of(end_prb_ul)
-                                .map(val -> new BerInteger(val.asInt()))
-                                .collect(Collectors.toList());
-                        endPrbUl.setSeqOf(collect);
-                    }
-                }
+
+                List<BerInteger> collect = Lists.newArrayList();
+                collect.add(new BerInteger(end_prb_ul.asInt()));
+                endPrbUl.setSeqOf(collect);
+
                 rrmParameters.setEndPrbUl(endPrbUl);
             }
         }
-
-        // TODO
     }
 
     public PDCPThroughput getPdcpThroughput() {
@@ -223,50 +214,6 @@
         this.resourceUsage = resourceUsage;
     }
 
-    private void setDefaultRRMConf() {
-        rrmParameters = new RRMConfig();
-
-        RRMConfig.Crnti crnti = new RRMConfig.Crnti();
-        crnti.addCRNTI(linkId.getUe().getRanId());
-
-        rrmParameters.setCrnti(crnti);
-
-        rrmParameters.setEcgi(linkId.getEcgi());
-
-        RRMConfig.StartPrbDl startPrbDl = new RRMConfig.StartPrbDl();
-        startPrbDl.addBerInteger(new BerInteger(0));
-        startPrbDl.addBerInteger(new BerInteger(50));
-
-        rrmParameters.setStartPrbDl(startPrbDl);
-
-        RRMConfig.StartPrbUl startPrbUl = new RRMConfig.StartPrbUl();
-        startPrbUl.addBerInteger(new BerInteger(50));
-        startPrbUl.addBerInteger(new BerInteger(100));
-
-        rrmParameters.setStartPrbUl(startPrbUl);
-
-        RRMConfig.EndPrbDl endPrbDl = new RRMConfig.EndPrbDl();
-        endPrbDl.addBerInteger(new BerInteger(50));
-        endPrbDl.addBerInteger(new BerInteger(100));
-
-        rrmParameters.setEndPrbDl(endPrbDl);
-
-        RRMConfig.EndPrbUl endPrbUl = new RRMConfig.EndPrbUl();
-        endPrbUl.addBerInteger(new BerInteger(50));
-        endPrbUl.addBerInteger(new BerInteger(100));
-
-        rrmParameters.setEndPrbUl(endPrbUl);
-
-        RRMConfig.SubframeBitmaskDl subframeBitmaskDl = new RRMConfig.SubframeBitmaskDl();
-        BerBitString berBitString = new BerBitString(new byte[]{(byte) 0xAA, (byte) 0x80}, 10);
-        BerBitString berBitString1 = new BerBitString(new byte[]{(byte) 0x55, (byte) 0x40}, 10);
-
-        subframeBitmaskDl.addBerBitString(berBitString);
-        subframeBitmaskDl.addBerBitString(berBitString1);
-
-        rrmParameters.setSubframeBitmaskDl(subframeBitmaskDl);
-    }
-
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
@@ -307,10 +254,16 @@
             }
         },
         // TODO: Add CA/DC
-        SERVING_SECONDARY("serving/secondary") {
+        SERVING_SECONDARY_CA("serving/secondary/ca") {
             @Override
             public String toString() {
-                return "\"serving/secondary\"";
+                return "\"serving/secondary/ca\"";
+            }
+        },
+        SERVING_SECONDARY_DC("serving/secondary/dc") {
+            @Override
+            public String toString() {
+                return "\"serving/secondary/dc\"";
             }
         },
         NON_SERVING("non-serving") {
diff --git a/src/main/java/org.onosproject.xran/impl/DefaultXranStore.java b/src/main/java/org.onosproject.xran/impl/DefaultXranStore.java
index 3cc0e01..d7b9904 100644
--- a/src/main/java/org.onosproject.xran/impl/DefaultXranStore.java
+++ b/src/main/java/org.onosproject.xran/impl/DefaultXranStore.java
@@ -19,7 +19,6 @@
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.google.common.collect.Lists;
-import org.apache.commons.lang.exception.ExceptionUtils;
 import org.apache.felix.scr.annotations.*;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
@@ -123,6 +122,7 @@
         return list;
     }
 
+
     @Override
     public RnibLink getLinkBetweenCellIdUeId(String eciHex, long euId) {
         EUTRANCellIdentifier eci = hexToECI(eciHex);
@@ -138,38 +138,21 @@
     }
 
     @Override
-    public boolean createLinkBetweenCellIdUeId(String eciHex, long euId, String type) {
-        RnibCell cell = getCell(eciHex);
-        RnibUe ue = getUe(euId);
-
-        if (cell != null && ue != null) {
-            RnibLink link = new RnibLink(cell, ue);
-
-            // TODO: check logic for each type
-            try {
-                RnibLink.Type linkType = RnibLink.Type.valueOf(type);
-                switch (linkType) {
-                    case NON_SERVING:
-                        break;
-                    case SERVING_PRIMARY:
-                        break;
-                    case SERVING_SECONDARY:
-                        break;
-                }
-            } catch (Exception e) {
-                log.error(ExceptionUtils.getFullStackTrace(e));
-            }
-            linkMap.put(link.getLinkId(), link);
-            return true;
-        }
-
-        return false;
-    }
-
-    @Override
     public void storeLink(RnibLink link) {
-        if (link.getLinkId() != null) {
-            linkMap.put(link.getLinkId(), link);
+        synchronized (this) {
+            if (link.getLinkId() != null) {
+                // if we add a primary link then change the primary to non serving
+                if (link.getType().equals(RnibLink.Type.SERVING_PRIMARY)) {
+                    RnibUe ue = link.getLinkId().getUe();
+                    getLinksByUeId(ue.getMmeS1apId().longValue())
+                            .forEach(l -> {
+                                if (l.getType().equals(RnibLink.Type.SERVING_PRIMARY)) {
+                                    l.setType(RnibLink.Type.NON_SERVING);
+                                }
+                            });
+                }
+                linkMap.put(link.getLinkId(), link);
+            }
         }
     }
 
diff --git a/src/main/java/org.onosproject.xran/rest/CellWebResource.java b/src/main/java/org.onosproject.xran/rest/CellWebResource.java
index c62cd0e..25825a9 100644
--- a/src/main/java/org.onosproject.xran/rest/CellWebResource.java
+++ b/src/main/java/org.onosproject.xran/rest/CellWebResource.java
@@ -94,8 +94,8 @@
             try {
                 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
 
-                JsonNode rrmConf = jsonTree.get("RRMConf");
-                if (rrmConf != null) {
+                JsonNode rrmConf = jsonTree.path("RRMConf");
+                if (!rrmConf.isMissingNode()) {
                     final SynchronousQueue<String>[] queue = new SynchronousQueue[1];
                     get(XranStore.class).modifyCellRrmConf(cell, rrmConf);
 
@@ -122,7 +122,9 @@
             }
         }
 
-        return Response.serverError().entity("cell not found").build();
+        return Response.serverError()
+                .entity("cell not found")
+                .build();
     }
 
 }
diff --git a/src/main/java/org.onosproject.xran/rest/LinkWebResource.java b/src/main/java/org.onosproject.xran/rest/LinkWebResource.java
index 3640a1d..e3b2035 100644
--- a/src/main/java/org.onosproject.xran/rest/LinkWebResource.java
+++ b/src/main/java/org.onosproject.xran/rest/LinkWebResource.java
@@ -23,19 +23,14 @@
 import org.onosproject.xran.XranStore;
 import org.onosproject.xran.annotations.Patch;
 import org.onosproject.xran.controller.XranController;
+import org.onosproject.xran.entities.RnibCell;
 import org.onosproject.xran.entities.RnibLink;
+import org.onosproject.xran.entities.RnibUe;
 import org.openmuc.jasn1.ber.types.BerInteger;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
+import javax.ws.rs.*;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import java.io.IOException;
@@ -110,62 +105,20 @@
             try {
                 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
 
-                JsonNode type = jsonTree.get("type");
-                if (type != null) {
-                    final SynchronousQueue<String>[] queue = new SynchronousQueue[1];
-                    RnibLink.Type linkType = RnibLink.Type.getEnum(type.asText());
-                    if (linkType.equals(RnibLink.Type.SERVING_PRIMARY)) {
-                        List<RnibLink> linksByUeId = get(XranStore.class).getLinksByUeId(dst);
-                        Optional<RnibLink> primary = linksByUeId.stream()
-                                .filter(l -> l.getType().equals(RnibLink.Type.SERVING_PRIMARY))
-                                .findFirst();
-                        if (primary.isPresent()) {
-                            queue[0] = get(XranController.class).sendHORequest(link, primary.get());
-                            String poll = queue[0].poll(5, TimeUnit.SECONDS);
-
-                            if (poll != null) {
-                                return Response.ok()
-                                        .entity(poll)
-                                        .build();
-                            } else {
-                                return Response.serverError()
-                                        .entity("did not receive response in time")
-                                        .build();
-                            }
-                        }
-                    }
+                JsonNode type = jsonTree.path("type");
+                if (!type.isMissingNode()) {
+                    RnibLink.Type anEnum = RnibLink.Type.getEnum(type.asText());
+                    return handleTypeChange(link, anEnum);
                 }
 
-                JsonNode trafficpercent = jsonTree.get("trafficpercent");
-                if (trafficpercent != null) {
-                    JsonNode jsonNode = trafficpercent.get("traffic-percent-dl");
-                    if (jsonNode != null) {
-                        link.getTrafficPercent().setTrafficPercentDl(new BerInteger(jsonNode.asInt()));
-                    }
-                    jsonNode = trafficpercent.get("traffic-percent-ul");
-                    if (jsonNode != null) {
-                        link.getTrafficPercent().setTrafficPercentUl(new BerInteger(jsonNode.asInt()));
-                    }
-                    return Response.ok("trafficpercent changed successfully").build();
+                JsonNode trafficpercent = jsonTree.path("trafficpercent");
+                if (!trafficpercent.isMissingNode()) {
+                    return handleTrafficChange(link, trafficpercent);
                 }
 
-                JsonNode rrmConf = jsonTree.get("RRMConf");
-                if (rrmConf != null) {
-                    final SynchronousQueue<String>[] queue = new SynchronousQueue[1];
-                    get(XranStore.class).modifyLinkRrmConf(link, rrmConf);
-                    queue[0] = get(XranController.class).sendModifiedRRMConf(link.getRrmParameters(),
-                            link.getLinkId().getCell().getVersion().equals("3"));
-                    String poll = queue[0].poll(5, TimeUnit.SECONDS);
-
-                    if (poll != null) {
-                        return Response.ok()
-                                .entity(poll)
-                                .build();
-                    } else {
-                        return Response.serverError()
-                                .entity("did not receive response in time")
-                                .build();
-                    }
+                JsonNode rrmConf = jsonTree.path("RRMConf");
+                if (!rrmConf.isMissingNode()) {
+                    return handleRRMChange(link, rrmConf);
                 }
 
             } catch (Exception e) {
@@ -174,7 +127,7 @@
                 return Response.serverError().entity(ExceptionUtils.getFullStackTrace(e)).build();
             }
         }
-        return Response.serverError().entity("link not found").build();
+        return Response.serverError().entity("link not found use POST request").build();
     }
 
     /**
@@ -189,15 +142,38 @@
     @Path("{src},{dst}")
     @Consumes(MediaType.APPLICATION_JSON)
     public Response postLinks(@PathParam("src") String src, @PathParam("dst") long dst, InputStream stream) {
+        RnibCell cell = get(XranStore.class).getCell(src);
+        RnibUe ue = get(XranStore.class).getUe(dst);
+
+        if (cell == null) {
+            return Response.serverError()
+                    .entity("cell not found")
+                    .build();
+        }
+
+        if (ue == null) {
+            return Response.serverError()
+                    .entity("ue not found")
+                    .build();
+        }
+
+        if (get(XranStore.class).getLink(cell.getEcgi(), ue.getMmeS1apId()) != null) {
+            return Response.serverError()
+                    .entity("link exists use PATCH request")
+                    .build();
+        }
+
         try {
             ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
 
-            JsonNode type = jsonTree.get("type");
+            JsonNode type = jsonTree.path("type");
 
-            if (type != null) {
-                boolean b;
-                b = get(XranStore.class).createLinkBetweenCellIdUeId(src, dst, type.asText());
-                return ok(b).build();
+            if (!type.isMissingNode()) {
+                RnibLink link = new RnibLink(cell, ue);
+                link.setType(RnibLink.Type.getEnum(type.asText()));
+                get(XranStore.class).storeLink(link);
+
+                // TODO: trigger the scell add
             }
         } catch (Exception e) {
             log.error(ExceptionUtils.getFullStackTrace(e));
@@ -207,7 +183,121 @@
                     .build();
         }
 
-        return Response.serverError().entity("unreachable code").build();
+        return Response.serverError()
+                .entity("unreachable code")
+                .build();
     }
 
+    private Response handleTypeChange(RnibLink link, RnibLink.Type newType) throws InterruptedException {
+        final SynchronousQueue<String>[] queue = new SynchronousQueue[1];
+
+        if (newType.equals(RnibLink.Type.SERVING_PRIMARY)) {
+            List<RnibLink> linksByUeId = get(XranStore.class).getLinksByUeId(link.getLinkId().getMmeues1apid().longValue());
+
+            Optional<RnibLink> primary = linksByUeId.stream()
+                    .filter(l -> l.getType().equals(RnibLink.Type.SERVING_PRIMARY))
+                    .findFirst();
+            if (primary.isPresent()) {
+                queue[0] = get(XranController.class).sendHORequest(link, primary.get());
+                String poll = queue[0].poll(5, TimeUnit.SECONDS);
+
+                if (poll != null) {
+                    return Response.ok()
+                            .entity(poll)
+                            .build();
+                } else {
+                    return Response.serverError()
+                            .entity("did not receive response in time")
+                            .build();
+                }
+            } else {
+                link.setType(RnibLink.Type.SERVING_PRIMARY);
+                return Response.ok()
+                        .entity("there was not another primary link")
+                        .build();
+            }
+        } else if (newType.equals(RnibLink.Type.NON_SERVING)) {
+            switch (link.getType()) {
+                case NON_SERVING:
+                    return Response.ok()
+                            .entity("It's already a non serving link!" + link)
+                            .build();
+                case SERVING_PRIMARY:
+                    return Response.serverError()
+                            .entity("Cannot change a Primary link.")
+                            .build();
+                case SERVING_SECONDARY_CA:
+                case SERVING_SECONDARY_DC:
+                    if (get(XranController.class).sendScellDelete(link)) {
+                        return Response.ok()
+                                .entity("Successfully changed link type to " + link.getType())
+                                .build();
+                    } else {
+                        return Response.serverError()
+                                .entity("Could not change link type.")
+                                .build();
+                    }
+            }
+        } else if (newType.equals(RnibLink.Type.SERVING_SECONDARY_CA)) {
+            switch (link.getType()) {
+                case SERVING_PRIMARY:
+                    return Response.serverError()
+                            .entity("Cannot change a Primary link.")
+                            .build();
+                case SERVING_SECONDARY_DC:
+                case NON_SERVING:
+                    queue[0] = get(XranController.class).sendScellAdd(link);
+                    String poll = queue[0].poll(5, TimeUnit.SECONDS);
+                    if (poll != null) {
+                        return Response.ok()
+                                .entity("Successfully changed link type to " + link.getType())
+                                .build();
+                    } else {
+                        return Response.serverError()
+                                .entity("did not receive response in time")
+                                .build();
+                    }
+                case SERVING_SECONDARY_CA:
+                    return Response.ok()
+                            .entity("It's already a service secondary ca link!")
+                            .build();
+            }
+        }
+
+        return Response.serverError()
+                .entity("Unknown type")
+                .build();
+    }
+
+    private Response handleTrafficChange(RnibLink link, JsonNode trafficpercent) {
+        JsonNode jsonNode = trafficpercent.path("traffic-percent-dl");
+        if (!jsonNode.isMissingNode()) {
+            link.getTrafficPercent().setTrafficPercentDl(new BerInteger(jsonNode.asInt()));
+        }
+
+        jsonNode = trafficpercent.path("traffic-percent-ul");
+        if (!jsonNode.isMissingNode()) {
+            link.getTrafficPercent().setTrafficPercentUl(new BerInteger(jsonNode.asInt()));
+        }
+
+        return Response.ok("trafficpercent changed successfully").build();
+    }
+
+    private Response handleRRMChange(RnibLink link, JsonNode rrmConf) throws InterruptedException {
+        final SynchronousQueue<String>[] queue = new SynchronousQueue[1];
+        get(XranStore.class).modifyLinkRrmConf(link, rrmConf);
+        queue[0] = get(XranController.class).sendModifiedRRMConf(link.getRrmParameters(),
+                link.getLinkId().getCell().getVersion().equals("3"));
+        String poll = queue[0].poll(5, TimeUnit.SECONDS);
+
+        if (poll != null) {
+            return Response.ok()
+                    .entity(poll)
+                    .build();
+        } else {
+            return Response.serverError()
+                    .entity("did not receive response in time")
+                    .build();
+        }
+    }
 }
diff --git a/src/main/java/org.onosproject.xran/wrapper/LinkMap.java b/src/main/java/org.onosproject.xran/wrapper/LinkMap.java
index 862acf6..033f132 100644
--- a/src/main/java/org.onosproject.xran/wrapper/LinkMap.java
+++ b/src/main/java/org.onosproject.xran/wrapper/LinkMap.java
@@ -45,15 +45,7 @@
     public void putPrimaryLink(RnibCell cell, RnibUe ue) {
         RnibLink link = new RnibLink(cell, ue);
         link.setType(RnibLink.Type.SERVING_PRIMARY);
-        synchronized (xranStore) {
-            xranStore.getLinksByUeId(ue.getMmeS1apId().longValue())
-                    .forEach(l -> {
-                        if (l.getType().equals(RnibLink.Type.SERVING_PRIMARY)) {
-                            l.setType(RnibLink.Type.SERVING_SECONDARY);
-                        }
-                    });
-            xranStore.storeLink(link);
-        }
+        xranStore.storeLink(link);
         crntiMme.put(ue.getRanId(), ue.getMmeS1apId());
     }
 
@@ -116,12 +108,14 @@
         return false;
     }
 
-    public ECGI getPrimaryCell(RnibUe ue) {
+    public RnibCell getPrimaryCell(RnibUe ue) {
         List<RnibLink> linksByUeId = xranStore.getLinksByUeId(ue.getMmeS1apId().longValue());
-        Optional<RnibLink> primary = linksByUeId.stream().filter(l -> l.getType().equals(RnibLink.Type.SERVING_PRIMARY)).findFirst();
+        Optional<RnibLink> primary = linksByUeId.stream()
+                .filter(l -> l.getType().equals(RnibLink.Type.SERVING_PRIMARY))
+                .findFirst();
 
         if (primary.isPresent()) {
-            return primary.get().getLinkId().getEcgi();
+            return primary.get().getLinkId().getCell();
         }
         return null;
     }