BUG-45 : migrated linkstate to generated source code.
[bgpcep.git] / bgp / parser-impl / src / main / java / org / opendaylight / protocol / bgp / parser / impl / message / update / LinkStateParser.java
index 226f7581f8a114d8e87effc86b114b13547d81d5..cc1a168b599b417dd4a516e5415c9f9dd553c859 100644 (file)
@@ -7,74 +7,82 @@
  */
 package org.opendaylight.protocol.bgp.parser.impl.message.update;
 
+import java.math.BigInteger;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
-import java.util.SortedSet;
-
-import org.opendaylight.protocol.bgp.linkstate.AdministrativeGroup;
-import org.opendaylight.protocol.bgp.linkstate.AreaIdentifier;
-import org.opendaylight.protocol.bgp.linkstate.DomainIdentifier;
-import org.opendaylight.protocol.bgp.linkstate.ExtendedRouteTag;
-import org.opendaylight.protocol.bgp.linkstate.IPv4InterfaceIdentifier;
-import org.opendaylight.protocol.bgp.linkstate.IPv4PrefixIdentifier;
-import org.opendaylight.protocol.bgp.linkstate.IPv4RouterIdentifier;
-import org.opendaylight.protocol.bgp.linkstate.IPv6InterfaceIdentifier;
-import org.opendaylight.protocol.bgp.linkstate.IPv6PrefixIdentifier;
-import org.opendaylight.protocol.bgp.linkstate.IPv6RouterIdentifier;
-import org.opendaylight.protocol.bgp.linkstate.ISISAreaIdentifier;
-import org.opendaylight.protocol.bgp.linkstate.ISISLANIdentifier;
-import org.opendaylight.protocol.bgp.linkstate.ISISNetworkPrefixState;
-import org.opendaylight.protocol.bgp.linkstate.ISISRouterIdentifier;
-import org.opendaylight.protocol.bgp.linkstate.InterfaceIdentifier;
-import org.opendaylight.protocol.bgp.linkstate.LinkAnchor;
-import org.opendaylight.protocol.bgp.linkstate.LinkIdentifier;
-import org.opendaylight.protocol.bgp.linkstate.LinkProtectionType;
-import org.opendaylight.protocol.bgp.linkstate.MPLSProtocol;
-import org.opendaylight.protocol.bgp.linkstate.NetworkLinkImpl;
-import org.opendaylight.protocol.bgp.linkstate.NetworkLinkState;
-import org.opendaylight.protocol.bgp.linkstate.NetworkNodeImpl;
-import org.opendaylight.protocol.bgp.linkstate.NetworkNodeState;
-import org.opendaylight.protocol.bgp.linkstate.NetworkObjectState;
-import org.opendaylight.protocol.bgp.linkstate.NetworkPrefixState;
-import org.opendaylight.protocol.bgp.linkstate.NodeIdentifier;
-import org.opendaylight.protocol.bgp.linkstate.OSPFInterfaceIdentifier;
-import org.opendaylight.protocol.bgp.linkstate.OSPFNetworkPrefixState;
-import org.opendaylight.protocol.bgp.linkstate.OSPFPrefixIdentifier;
-import org.opendaylight.protocol.bgp.linkstate.OSPFRouteType;
-import org.opendaylight.protocol.bgp.linkstate.OSPFRouterIdentifier;
-import org.opendaylight.protocol.bgp.linkstate.OSPFv3LANIdentifier;
-import org.opendaylight.protocol.bgp.linkstate.PrefixIdentifier;
-import org.opendaylight.protocol.bgp.linkstate.RouteTag;
-import org.opendaylight.protocol.bgp.linkstate.RouterIdentifier;
-import org.opendaylight.protocol.bgp.linkstate.TopologyIdentifier;
-import org.opendaylight.protocol.bgp.linkstate.UnnumberedLinkIdentifier;
+
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
-import org.opendaylight.protocol.bgp.parser.impl.BGPLinkMP;
-import org.opendaylight.protocol.bgp.parser.impl.BGPNodeMP;
 import org.opendaylight.protocol.bgp.parser.impl.ByteList;
-import org.opendaylight.protocol.bgp.parser.impl.MPReach;
-import org.opendaylight.protocol.concepts.IGPMetric;
-import org.opendaylight.protocol.concepts.IPv4Address;
-import org.opendaylight.protocol.concepts.IPv4Prefix;
-import org.opendaylight.protocol.concepts.IPv6;
-import org.opendaylight.protocol.concepts.IPv6Address;
-import org.opendaylight.protocol.concepts.IPv6Prefix;
-import org.opendaylight.protocol.concepts.Metric;
-import org.opendaylight.protocol.concepts.Prefix;
-import org.opendaylight.protocol.concepts.SharedRiskLinkGroup;
-import org.opendaylight.protocol.concepts.TEMetric;
+import org.opendaylight.protocol.concepts.Ipv4Util;
+import org.opendaylight.protocol.concepts.Ipv6Util;
 import org.opendaylight.protocol.util.ByteArray;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.AdministrativeGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.AreaIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.DomainIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.ExtendedRouteTag;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.Identifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.IgpBits.UpDown;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.Ipv4InterfaceIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.Ipv4RouterIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.Ipv6InterfaceIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.Ipv6RouterIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.IsisAreaIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.LinkProtectionType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.MplsProtocolMask;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.NlriType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.NodeFlagBits;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.NodeIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.OspfInterfaceIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.OspfRouteType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.ProtocolId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.RouteDistinguisher;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.RouteTag;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.SharedRiskLinkGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.TopologyIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.isis.lan.identifier.IsIsRouterIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.isis.lan.identifier.IsIsRouterIdentifierBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.link.state.UnreservedBandwidthBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.CLinkstateDestination;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.CLinkstateDestinationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.LinkDescriptors;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.LinkDescriptorsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.LocalNodeDescriptors;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.LocalNodeDescriptorsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.PrefixDescriptors;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.PrefixDescriptorsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.linkstate.destination.c.linkstate.destination.RemoteNodeDescriptors;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.CRouterIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.CIsisNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.CIsisPseudonodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.COspfNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.COspfPseudonodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.c.isis.node.IsisNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.c.isis.pseudonode.IsisPseudonodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.c.ospf.node.OspfNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.node.identifier.c.router.identifier.c.ospf.pseudonode.OspfPseudonodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.prefix.state.IgpBitsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.update.path.attributes.LinkstatePathAttribute;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.update.path.attributes.LinkstatePathAttributeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.update.path.attributes.linkstate.path.attribute.link.state.attribute.LinkAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.update.path.attributes.linkstate.path.attribute.link.state.attribute.LinkAttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.update.path.attributes.linkstate.path.attribute.link.state.attribute.NodeAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.update.path.attributes.linkstate.path.attribute.link.state.attribute.NodeAttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.update.path.attributes.linkstate.path.attribute.link.state.attribute.PrefixAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.update.path.attributes.linkstate.path.attribute.link.state.attribute.PrefixAttributesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.MplsLabeledVpnSubsequentAddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.SubsequentAddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nps.concepts.rev130930.Bandwidth;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nps.concepts.rev130930.IgpMetric;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nps.concepts.rev130930.IsoSystemIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nps.concepts.rev130930.Metric;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nps.concepts.rev130930.TeMetric;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -109,10 +117,6 @@ public class LinkStateParser {
 
        private static final Set<Integer> prefixTlvs = Sets.newHashSet(1152, 1153, 1154, 1155, 1156, 1157);
 
-       private enum NlriType {
-               LinkNLRI, NodeNLRI, IPv4Prefixes, IPv6Prefixes
-       }
-
        private LinkStateParser() {
        }
 
@@ -125,37 +129,41 @@ public class LinkStateParser {
         * @return BGPLinkMP or BGPNodeMP
         * @throws BGPParsingException
         */
-       protected static MPReach<?> parseLSNlri(final boolean reachable, final Class<? extends SubsequentAddressFamily> safi,
-                       final CNextHop nextHop, final byte[] bytes) throws BGPParsingException {
+       protected static CLinkstateDestination parseLSNlri(final Class<? extends SubsequentAddressFamily> safi, final byte[] bytes)
+                       throws BGPParsingException {
                if (bytes.length == 0) {
                        return null;
                }
                int byteOffset = 0;
-               final Set<LinkIdentifier> links = Sets.newHashSet();
-               final Set<NodeIdentifier> nodes = Sets.newHashSet();
-               final Set<PrefixIdentifier<?>> descs = Sets.newHashSet();
 
-               long identifier = 0;
-               ProtocolId sp = null;
+               final CLinkstateDestinationBuilder builder = new CLinkstateDestinationBuilder();
 
                while (byteOffset != bytes.length) {
-                       final NlriType type = parseNLRItype(ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, TYPE_LENGTH)));
+                       final NlriType type = NlriType.forValue(ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, TYPE_LENGTH)));
+                       builder.setNlriType(type);
+
                        byteOffset += TYPE_LENGTH;
                        // length means total length of the tlvs including route distinguisher not including the type field
                        final int length = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, LENGTH_SIZE));
                        byteOffset += LENGTH_SIZE;
+                       RouteDistinguisher distinguisher = null;
                        if (safi == MplsLabeledVpnSubsequentAddressFamily.class) {
                                // this parses route distinguisher
-                               ByteArray.bytesToLong(ByteArray.subByte(bytes, byteOffset, ROUTE_DISTINGUISHER_LENGTH));
+                               distinguisher = new RouteDistinguisher(BigInteger.valueOf(ByteArray.bytesToLong(ByteArray.subByte(bytes, byteOffset,
+                                               ROUTE_DISTINGUISHER_LENGTH))));
+                               builder.setDistinguisher(distinguisher);
                                byteOffset += ROUTE_DISTINGUISHER_LENGTH;
                        }
                        // parse source protocol
-                       sp = ProtocolId.forValue(ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, PROTOCOL_ID_LENGTH)));
+                       final ProtocolId sp = ProtocolId.forValue(ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, PROTOCOL_ID_LENGTH)));
                        byteOffset += PROTOCOL_ID_LENGTH;
+                       builder.setProtocolId(sp);
 
                        // parse identifier
-                       identifier = ByteArray.bytesToLong(ByteArray.subByte(bytes, byteOffset, IDENTIFIER_LENGTH));
+                       final Identifier identifier = new Identifier(BigInteger.valueOf(ByteArray.bytesToLong(ByteArray.subByte(bytes, byteOffset,
+                                       IDENTIFIER_LENGTH))));
                        byteOffset += IDENTIFIER_LENGTH;
+                       builder.setIdentifier(identifier);
 
                        // if we are dealing with linkstate nodes/links, parse local node descriptor
                        NodeIdentifier localDescriptor = null;
@@ -168,49 +176,25 @@ public class LinkStateParser {
                                localDescriptor = parseNodeDescriptors(ByteArray.subByte(bytes, byteOffset, locallength));
                        }
                        byteOffset += locallength;
+                       builder.setLocalNodeDescriptors((LocalNodeDescriptors) localDescriptor);
                        final int restLength = length - ((safi == MplsLabeledVpnSubsequentAddressFamily.class) ? ROUTE_DISTINGUISHER_LENGTH : 0)
                                        - PROTOCOL_ID_LENGTH - IDENTIFIER_LENGTH - TYPE_LENGTH - LENGTH_SIZE - locallength;
                        logger.debug("Restlength {}", restLength);
                        switch (type) {
-                       case LinkNLRI:
-                               links.add(parseLink(localDescriptor, sp, ByteArray.subByte(bytes, byteOffset, restLength)));
+                       case Link:
+                               parseLink(builder, ByteArray.subByte(bytes, byteOffset, restLength));
                                break;
-                       case IPv4Prefixes:
-                       case IPv6Prefixes:
-                               descs.add(parsePrefixDescriptors(localDescriptor, ByteArray.subByte(bytes, byteOffset, restLength)));
+                       case Ipv4Prefix:
+                       case Ipv6Prefix:
+                               builder.setPrefixDescriptors(parsePrefixDescriptors(localDescriptor, ByteArray.subByte(bytes, byteOffset, restLength)));
                                break;
-                       case NodeNLRI:
+                       case Node:
                                // node nlri is already parsed as it contains only the common fields for node and link nlri
-                               nodes.add(localDescriptor);
                                break;
                        }
                        byteOffset += restLength;
                }
-               if (!links.isEmpty()) {
-                       return new BGPLinkMP(identifier, sp, reachable, links);
-               } else if (!nodes.isEmpty()) {
-                       return new BGPNodeMP(identifier, sp, reachable, nodes);
-               }
-               // else if (!descs.isEmpty())
-               // return new BGPIPv4PrefixMP(identifier, sp, descs, reachable);
-               return null;
-       }
-
-       protected static Map<Integer, ByteList> parseLinkState(final byte[] bytes) {
-               final Map<Integer, ByteList> map = new HashMap<Integer, ByteList>();
-               int byteOffset = 0;
-               while (byteOffset != bytes.length) {
-                       final int type = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, TYPE_LENGTH));
-                       byteOffset += TYPE_LENGTH;
-                       final int length = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, LENGTH_SIZE));
-                       byteOffset += LENGTH_SIZE;
-                       final byte[] value = ByteArray.subByte(bytes, byteOffset, length);
-                       ByteList values = map.containsKey(type) ? values = map.get(type) : new ByteList();
-                       values.add(value);
-                       map.put(type, values);
-                       byteOffset += length;
-               }
-               return map;
+               return builder.build();
        }
 
        public static boolean verifyLink(final Set<Integer> keys) {
@@ -243,59 +227,24 @@ public class LinkStateParser {
                return true;
        }
 
-       private static OSPFRouteType parseRouteType(final int type) throws BGPParsingException {
-               switch (type) {
-               case 0:
-                       return null; // for IS-IS it needs to be 0
-               case 1:
-                       return OSPFRouteType.Intra_Area;
-               case 2:
-                       return OSPFRouteType.Inter_Area;
-               case 3:
-                       return OSPFRouteType.External1;
-               case 4:
-                       return OSPFRouteType.External2;
-               case 5:
-                       return OSPFRouteType.NSSA1;
-               case 6:
-                       return OSPFRouteType.NSSA2;
-               default:
-                       throw new BGPParsingException("Unknown OSPF Route Type: " + type);
-               }
-       }
-
-       private static LinkIdentifier parseLink(final NodeIdentifier local, final ProtocolId spi, final byte[] bytes)
-                       throws BGPParsingException {
+       private static NodeIdentifier parseLink(final CLinkstateDestinationBuilder builder, final byte[] bytes) throws BGPParsingException {
                int byteOffset = 0;
                final int type = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, TYPE_LENGTH));
                byteOffset += TYPE_LENGTH;
                final int length = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, LENGTH_SIZE));
                byteOffset += LENGTH_SIZE;
-               NodeIdentifier remote = null;
+               final NodeIdentifier remote = null;
                if (type == 257) {
-                       remote = parseNodeDescriptors(ByteArray.subByte(bytes, byteOffset, length));
+                       builder.setRemoteNodeDescriptors((RemoteNodeDescriptors) parseNodeDescriptors(ByteArray.subByte(bytes, byteOffset, length)));
                        byteOffset += length;
                }
-
-               return parseLinkDescriptors(local, remote, ByteArray.subByte(bytes, byteOffset, bytes.length - byteOffset));
+               builder.setLinkDescriptors(parseLinkDescriptors(ByteArray.subByte(bytes, byteOffset, bytes.length - byteOffset)));
+               return remote;
        }
 
-       /**
-        * Parse Link Descriptors.
-        * 
-        * @param topology
-        * @param localAnchor
-        * @param remoteAnchor
-        * @param bytes
-        * @return
-        * @throws BGPParsingException
-        */
-       private static LinkIdentifier parseLinkDescriptors(final NodeIdentifier local, final NodeIdentifier remote, final byte[] bytes)
-                       throws BGPParsingException {
+       private static LinkDescriptors parseLinkDescriptors(final byte[] bytes) throws BGPParsingException {
                int byteOffset = 0;
-               final List<InterfaceIdentifier> localIdentifiers = Lists.newArrayList();
-               final List<InterfaceIdentifier> remoteIdentifiers = Lists.newArrayList();
-               TopologyIdentifier topId = null;
+               final LinkDescriptorsBuilder builder = new LinkDescriptorsBuilder();
                while (byteOffset != bytes.length) {
                        final int type = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, TYPE_LENGTH));
                        byteOffset += TYPE_LENGTH;
@@ -305,34 +254,34 @@ public class LinkStateParser {
                        logger.debug("Parsing Link Descriptor: {}", Arrays.toString(value));
                        switch (type) {
                        case 258:
-                               final UnnumberedLinkIdentifier l = new UnnumberedLinkIdentifier(ByteArray.bytesToLong(ByteArray.subByte(value, 0, 4)));
-                               final UnnumberedLinkIdentifier r = new UnnumberedLinkIdentifier(ByteArray.bytesToLong(ByteArray.subByte(value, 4, 4)));
-                               localIdentifiers.add(l);
-                               remoteIdentifiers.add(r);
-                               logger.trace("Parsed link local {} remote {} Identifiers.", local, remote);
+                               builder.setLinkLocalIdentifier(ByteArray.subByte(value, 0, 4));
+                               builder.setLinkRemoteIdentifier(ByteArray.subByte(value, 4, 4));
+                               logger.trace("Parsed link local {} remote {} Identifiers.", builder.getLinkLocalIdentifier(),
+                                               builder.getLinkRemoteIdentifier());
                                break;
                        case 259:
-                               final IPv4InterfaceIdentifier lipv4 = new IPv4InterfaceIdentifier(new IPv4Address(value));
-                               localIdentifiers.add(lipv4);
+                               final Ipv4InterfaceIdentifier lipv4 = new Ipv4InterfaceIdentifier(Ipv4Util.addressForBytes(value));
+                               builder.setIpv4InterfaceAddress(lipv4);
                                logger.trace("Parsed IPv4 interface address {}.", lipv4);
                                break;
                        case 260:
-                               final IPv4InterfaceIdentifier ripv4 = new IPv4InterfaceIdentifier(new IPv4Address(value));
-                               remoteIdentifiers.add(ripv4);
+                               final Ipv4InterfaceIdentifier ripv4 = new Ipv4InterfaceIdentifier(Ipv4Util.addressForBytes(value));
+                               builder.setIpv4NeighborAddress(ripv4);
                                logger.trace("Parsed IPv4 neighbor address {}.", ripv4);
                                break;
                        case 261:
-                               final IPv6InterfaceIdentifier lipv6 = new IPv6InterfaceIdentifier(new IPv6Address(value));
-                               localIdentifiers.add(lipv6);
+                               final Ipv6InterfaceIdentifier lipv6 = new Ipv6InterfaceIdentifier(Ipv6Util.addressForBytes(value));
+                               builder.setIpv6InterfaceAddress(lipv6);
                                logger.trace("Parsed IPv6 interface address {}.", lipv6);
                                break;
                        case 262:
-                               final IPv6InterfaceIdentifier ripv6 = new IPv6InterfaceIdentifier(new IPv6Address(value));
-                               remoteIdentifiers.add(ripv6);
+                               final Ipv6InterfaceIdentifier ripv6 = new Ipv6InterfaceIdentifier(Ipv6Util.addressForBytes(value));
+                               builder.setIpv6NeighborAddress(ripv6);
                                logger.trace("Parsed IPv6 neighbor address {}.", ripv6);
                                break;
                        case 263:
-                               topId = new TopologyIdentifier(ByteArray.bytesToLong(value) & 0x3fff);
+                               final TopologyIdentifier topId = new TopologyIdentifier(ByteArray.bytesToInt(value) & 0x3fff);
+                               builder.setMultiTopologyId(topId);
                                logger.trace("Parsed topology identifier {}.", topId);
                                break;
                        default:
@@ -341,33 +290,15 @@ public class LinkStateParser {
                        byteOffset += length;
                }
                logger.debug("Finished parsing Link descriptors.");
-               if (localIdentifiers.size() != 1) {
-                       throw new BGPParsingException("Invalid number of local interface identifiers.");
-               }
-               final LinkAnchor localAnchor = new LinkAnchor(local, localIdentifiers.get(0));
-               LinkAnchor remoteAnchor = null;
-               if (remoteIdentifiers.size() > 0) {
-                       remoteAnchor = new LinkAnchor(remote, remoteIdentifiers.get(0));
-               } else {
-                       remoteAnchor = new LinkAnchor(remote, null);
-               }
-               return new LinkIdentifier(topId, localAnchor, remoteAnchor);
+               return builder.build();
        }
 
-       /**
-        * Parse Node Descriptors. There can be only one TLV present from each type.
-        * 
-        * @param spi
-        * @param bytes
-        * @return
-        * @throws BGPParsingException
-        */
        private static NodeIdentifier parseNodeDescriptors(final byte[] bytes) throws BGPParsingException {
                int byteOffset = 0;
                AsNumber asnumber = null;
                DomainIdentifier bgpId = null;
                AreaIdentifier ai = null;
-               RouterIdentifier routerId = null;
+               CRouterIdentifier routerId = null;
                while (byteOffset != bytes.length) {
                        final int type = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, TYPE_LENGTH));
                        byteOffset += TYPE_LENGTH;
@@ -390,21 +321,28 @@ public class LinkStateParser {
                                break;
                        case 515:
                                if (value.length == 6) {
-                                       routerId = new ISISRouterIdentifier(new IsoSystemIdentifier(ByteArray.subByte(value, 0, 6)));
+                                       routerId = new CIsisNodeBuilder().setIsisNode(
+                                                       new IsisNodeBuilder().setIsoSystemId(new IsoSystemIdentifier(ByteArray.subByte(value, 0, 6))).build()).build();
                                } else if (value.length == 7) {
                                        if (value[6] == 0) {
                                                logger.warn("PSN octet is 0. Ignoring System ID.");
-                                               routerId = new ISISRouterIdentifier(new IsoSystemIdentifier(ByteArray.subByte(value, 0, 6)));
+                                               routerId = new CIsisNodeBuilder().setIsisNode(
+                                                               new IsisNodeBuilder().setIsoSystemId(new IsoSystemIdentifier(ByteArray.subByte(value, 0, 6))).build()).build();
                                                break;
                                        } else {
-                                               routerId = new ISISLANIdentifier(new IsoSystemIdentifier(ByteArray.subByte(value, 0, 6)), value[6]);
+                                               final IsIsRouterIdentifier iri = new IsIsRouterIdentifierBuilder().setIsoSystemId(
+                                                               new IsoSystemIdentifier(ByteArray.subByte(value, 0, 6))).build();
+                                               routerId = new CIsisPseudonodeBuilder().setIsisPseudonode(
+                                                               new IsisPseudonodeBuilder().setIsIsRouterIdentifier(iri).setPsn((short) UnsignedBytes.toInt(value[6])).build()).build();
                                        }
                                } else if (value.length == 4) {
-                                       routerId = new OSPFRouterIdentifier(ByteArray.subByte(value, 0, 4));
+                                       routerId = new COspfNodeBuilder().setOspfNode(
+                                                       new OspfNodeBuilder().setOspfRouterId(ByteArray.subByte(value, 0, 4)).build()).build();
                                } else if (value.length == 8) {
                                        final byte[] o = ByteArray.subByte(value, 0, 4); // FIXME: OSPFv3 vs OSPFv2
-                                       final OSPFInterfaceIdentifier a = new OSPFInterfaceIdentifier(ByteArray.subByte(value, 4, 4));
-                                       routerId = new OSPFv3LANIdentifier(new OSPFRouterIdentifier(o), a);
+                                       final OspfInterfaceIdentifier a = new OspfInterfaceIdentifier(ByteArray.subByte(value, 4, 4));
+                                       routerId = new COspfPseudonodeBuilder().setOspfPseudonode(
+                                                       new OspfPseudonodeBuilder().setOspfRouterId(o).setLanInterface(a).build()).build();
                                }
                                logger.trace("Parsed Router Identifier {}", routerId);
                                break;
@@ -414,15 +352,13 @@ public class LinkStateParser {
                        byteOffset += length;
                }
                logger.debug("Finished parsing Node descriptors.");
-               return new NodeIdentifier(asnumber, bgpId, ai, routerId);
+               return new LocalNodeDescriptorsBuilder().setAsNumber(asnumber).setDomainId(bgpId).setAreaId(ai).setCRouterIdentifier(routerId).build();
        }
 
-       private static PrefixIdentifier<?> parsePrefixDescriptors(final NodeIdentifier localDescriptor, final byte[] bytes)
+       private static PrefixDescriptors parsePrefixDescriptors(final NodeIdentifier localDescriptor, final byte[] bytes)
                        throws BGPParsingException {
                int byteOffset = 0;
-               TopologyIdentifier topologyId = null;
-               OSPFRouteType routeType = null;
-               Prefix<?> prefix = null;
+               final PrefixDescriptorsBuilder builder = new PrefixDescriptorsBuilder();
                while (byteOffset != bytes.length) {
                        final int type = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, TYPE_LENGTH));
                        byteOffset += TYPE_LENGTH;
@@ -432,22 +368,31 @@ public class LinkStateParser {
                        logger.trace("Parsing Prefix Descriptor: {}", Arrays.toString(value));
                        switch (type) {
                        case 263:
-                               topologyId = new TopologyIdentifier(ByteArray.bytesToLong(value) & 0x3fff);
+                               final TopologyIdentifier topologyId = new TopologyIdentifier(ByteArray.bytesToInt(value) & 0x3fff);
+                               builder.setMultiTopologyId(topologyId);
                                logger.trace("Parsed Topology Identifier: {}", topologyId);
                                break;
                        case 264:
                                final int rt = ByteArray.bytesToInt(value);
-                               routeType = parseRouteType(rt);
+                               final OspfRouteType routeType = OspfRouteType.forValue(rt);
+                               if (routeType == null)
+                                       throw new BGPParsingException("Unknown OSPF Route Type: " + rt);
+                               builder.setOspfRouteType(routeType);
                                logger.trace("Parser RouteType: {}", routeType);
                                break;
                        case 265:
+                               IpPrefix prefix = null;
                                final int prefixLength = UnsignedBytes.toInt(value[0]);
                                final int size = prefixLength / 8 + ((prefixLength % 8 == 0) ? 0 : 1);
                                if (size != value.length - 1) {
                                        logger.debug("Expected length {}, actual length {}.", size, value.length - 1);
                                        throw new BGPParsingException("Illegal length of IP reachability TLV: " + (value.length - 1));
                                }
-                               prefix = IPv6.FAMILY.prefixForBytes(ByteArray.subByte(value, 1, size), prefixLength);
+                               if (size == 4)
+                                       prefix = new IpPrefix(Ipv4Util.prefixForBytes(ByteArray.subByte(value, 1, size), prefixLength));
+                               else
+                                       prefix = new IpPrefix(Ipv6Util.prefixForBytes(ByteArray.subByte(value, 1, size), prefixLength));
+                               builder.setIpReachabilityInformation(prefix);
                                logger.trace("Parsed IP reachability info: {}", prefix);
                                break;
                        default:
@@ -456,36 +401,44 @@ public class LinkStateParser {
                        byteOffset += length;
                }
                logger.debug("Finished parsing Prefix descriptors.");
-               if (routeType != null) {
-                       if (prefix instanceof IPv4Prefix) {
-                               return new OSPFPrefixIdentifier<IPv4Address>(localDescriptor, (IPv4Prefix) prefix, routeType);
-                       } else {
-                               return new OSPFPrefixIdentifier<IPv6Address>(localDescriptor, (IPv6Prefix) prefix, routeType);
-                       }
+               return builder.build();
+       }
+
+       protected static LinkstatePathAttribute parseLinkState(final byte[] bytes) throws BGPParsingException {
+               final Map<Integer, ByteList> map = new HashMap<Integer, ByteList>();
+               int byteOffset = 0;
+               while (byteOffset != bytes.length) {
+                       final int type = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, TYPE_LENGTH));
+                       byteOffset += TYPE_LENGTH;
+                       final int length = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, LENGTH_SIZE));
+                       byteOffset += LENGTH_SIZE;
+                       final byte[] value = ByteArray.subByte(bytes, byteOffset, length);
+                       ByteList values = map.containsKey(type) ? values = map.get(type) : new ByteList();
+                       values.add(value);
+                       map.put(type, values);
+                       byteOffset += length;
+               }
+               final LinkstatePathAttributeBuilder builder = new LinkstatePathAttributeBuilder();
+               if (verifyLink(map.keySet())) {
+                       builder.setLinkStateAttribute(parseLinkAttributes(map));
+               } else if (verifyNode(map.keySet())) {
+                       builder.setLinkStateAttribute(parseNodeAttributes(map));
+               } else if (verifyPrefix(map.keySet())) {
+                       builder.setLinkStateAttribute(parsePrefixAttributes(map));
                }
-               return (prefix instanceof IPv4Prefix) ? new IPv4PrefixIdentifier(localDescriptor, (IPv4Prefix) prefix)
-                               : new IPv6PrefixIdentifier(localDescriptor, (IPv6Prefix) prefix);
+               return builder.build();
        }
 
        /**
         * Parse Link Attributes.
         * 
-        * @param descriptors
-        * @param bytes
-        * @return
-        * @throws BGPParsingException
+        * @param attributes key is the tlv type and value is the value of the tlv
+        * @return {@link LinkAttributes}
+        * @throws BGPParsingException if a link attribute is not recognized
         */
-       public static NetworkLinkImpl parseLinkAttributes(final LinkIdentifier linkId, final Map<Integer, ByteList> attributes)
-                       throws BGPParsingException {
+       public static LinkAttributes parseLinkAttributes(final Map<Integer, ByteList> attributes) throws BGPParsingException {
 
-               final Set<SharedRiskLinkGroup> sharedRiskLinkGroups = Sets.newHashSet();
-               final Set<MPLSProtocol> enabledMPLSProtocols = Sets.newHashSet();
-               NetworkLinkState state = NetworkLinkState.EMPTY;
-
-               final Set<RouterIdentifier> localIds = Sets.newHashSet();
-               final Set<RouterIdentifier> remoteIds = Sets.newHashSet();
-
-               String name = null;
+               final LinkAttributesBuilder builder = new LinkAttributesBuilder();
                for (final Entry<Integer, ByteList> entry : attributes.entrySet()) {
                        logger.debug("Link attribute TLV {}", entry.getKey());
 
@@ -493,75 +446,76 @@ public class LinkStateParser {
 
                                switch (entry.getKey()) {
                                case 1028:
-                                       final IPv4RouterIdentifier lipv4 = new IPv4RouterIdentifier(new IPv4Address(value));
-                                       localIds.add(lipv4);
+                                       final Ipv4RouterIdentifier lipv4 = new Ipv4RouterIdentifier(Ipv4Util.addressForBytes(value));
+                                       builder.setLocalIpv4RouterId(lipv4);
                                        logger.trace("Parsed IPv4 Router-ID of local node: {}", lipv4);
                                        break;
                                case 1029:
-                                       final IPv6RouterIdentifier lipv6 = new IPv6RouterIdentifier(new IPv6Address(value));
-                                       localIds.add(lipv6);
+                                       final Ipv6RouterIdentifier lipv6 = new Ipv6RouterIdentifier(Ipv6Util.addressForBytes(value));
+                                       builder.setLocalIpv6RouterId(lipv6);
                                        logger.trace("Parsed IPv6 Router-ID of local node: {}", lipv6);
                                        break;
                                case 1030:
-                                       final IPv4RouterIdentifier ripv4 = new IPv4RouterIdentifier(new IPv4Address(value));
-                                       remoteIds.add(ripv4);
+                                       final Ipv4RouterIdentifier ripv4 = new Ipv4RouterIdentifier(Ipv4Util.addressForBytes(value));
+                                       builder.setRemoteIpv4RouterId(ripv4);
                                        logger.trace("Parsed IPv4 Router-ID of remote node: {}", ripv4);
                                        break;
                                case 1031:
-                                       final IPv6RouterIdentifier ripv6 = new IPv6RouterIdentifier(new IPv6Address(value));
-                                       remoteIds.add(ripv6);
+                                       final Ipv6RouterIdentifier ripv6 = new Ipv6RouterIdentifier(Ipv6Util.addressForBytes(value));
+                                       builder.setRemoteIpv6RouterId(ripv6);
                                        logger.trace("Parsed IPv6 Router-ID of remote node: {}", ripv6);
                                        break;
                                case 1088:
-                                       state = state.withAdministrativeGroup(new AdministrativeGroup(ByteArray.bytesToLong(value)));
-                                       logger.trace("Parsed Administrative Group {}", state.getAdministrativeGroup());
+                                       builder.setAdminGroup(new AdministrativeGroup(ByteArray.bytesToLong(value)));
+                                       logger.trace("Parsed Administrative Group {}", builder.getAdminGroup());
                                        break;
                                case 1089:
-                                       state = state.withMaximumBandwidth(new Bandwidth(value));
-                                       logger.trace("Parsed Max Bandwidth {}", state.getMaximumBandwidth());
+                                       builder.setMaxLinkBandwidth(new Bandwidth(value));
+                                       logger.trace("Parsed Max Bandwidth {}", builder.getMaxLinkBandwidth());
                                        break;
                                case 1090:
-                                       state = state.withReservableBandwidth(new Bandwidth(value));
-                                       logger.trace("Parsed Max Reservable Bandwidth {}", state.getMaximumReservableBandwidth());
+                                       builder.setMaxReservableBandwidth(new Bandwidth(value));
+                                       logger.trace("Parsed Max Reservable Bandwidth {}", builder.getMaxReservableBandwidth());
                                        break;
                                case 1091:
                                        int index = 0;
-                                       final Bandwidth[] unreservedBandwidth = new Bandwidth[8];
+                                       final List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.link.state.UnreservedBandwidth> unreservedBandwidth = Lists.newArrayList();
                                        for (int i = 0; i < 8; i++) {
-                                               unreservedBandwidth[i] = new Bandwidth(ByteArray.subByte(value, index, 4));
+                                               unreservedBandwidth.add(new UnreservedBandwidthBuilder().setBandwidth(
+                                                               new Bandwidth(ByteArray.subByte(value, index, 4))).setPriority((short) i).build());
                                                index += 4;
                                        }
-                                       state = state.withUnreservedBandwidth(unreservedBandwidth);
-                                       logger.trace("Parsed Unreserved Bandwidth {}", Arrays.toString(state.getUnreservedBandwidth()));
+                                       builder.setUnreservedBandwidth(unreservedBandwidth);
+                                       logger.trace("Parsed Unreserved Bandwidth {}", builder.getUnreservedBandwidth());
                                        break;
                                case 1092:
-                                       state = state.withMetric(TEMetric.class, new TEMetric(ByteArray.bytesToInt(value)));
-                                       logger.trace("Parsed Metric {}", state.getMetric(TEMetric.class));
+                                       builder.setTeMetric(new TeMetric(ByteArray.bytesToLong(value)));
+                                       logger.trace("Parsed Metric {}", builder.getTeMetric());
                                        break;
                                case 1093:
-                                       state = state.withProtectionType(parseLinkProtectionType(UnsignedBytes.toInt(value[0])));
-                                       logger.trace("Parsed Link Protection Type {}", state.getProtectionType());
+                                       final LinkProtectionType lpt = LinkProtectionType.forValue(UnsignedBytes.toInt(value[0]));
+                                       if (lpt == null)
+                                               throw new BGPParsingException("Link Protection Type not recognized: " + UnsignedBytes.toInt(value[0]));
+                                       builder.setLinkProtection(lpt);
+                                       logger.trace("Parsed Link Protection Type {}", lpt);
                                        break;
                                case 1094:
                                        final boolean[] bits = ByteArray.parseBits(value[0]);
-                                       if (bits[0] == true) {
-                                               enabledMPLSProtocols.add(MPLSProtocol.LDP);
-                                       }
-                                       if (bits[1] == true) {
-                                               enabledMPLSProtocols.add(MPLSProtocol.RSVPTE);
-                                       }
-                                       logger.trace("Parsed MPLS Protocols: {}", Arrays.toString(enabledMPLSProtocols.toArray()));
+                                       builder.setMplsProtocol(new MplsProtocolMask(bits[0], bits[1]));
+                                       logger.trace("Parsed MPLS Protocols: {}", builder.getMplsProtocol());
                                        break;
                                case 1095:
-                                       state = state.withDefaultMetric(new IGPMetric(ByteArray.bytesToLong(value)));
-                                       logger.trace("Parsed Metric {}", state.getDefaultMetric());
+                                       builder.setMetric(new Metric(ByteArray.bytesToLong(value)));
+                                       logger.trace("Parsed Metric {}", builder.getMetric());
                                        break;
                                case 1096:
                                        int i = 0;
+                                       final List<SharedRiskLinkGroup> sharedRiskLinkGroups = Lists.newArrayList();
                                        while (i != value.length) {
                                                sharedRiskLinkGroups.add(new SharedRiskLinkGroup(ByteArray.bytesToLong(ByteArray.subByte(value, i, 4))));
                                                i += 4;
                                        }
+                                       builder.setSharedRiskLinkGroups(sharedRiskLinkGroups);
                                        logger.trace("Parsed Shared Risk Link Groups {}", Arrays.toString(sharedRiskLinkGroups.toArray()));
                                        break;
                                case 1097:
@@ -569,7 +523,8 @@ public class LinkStateParser {
                                        logger.trace("Parsed Opaque value : {}", Arrays.toString(opaque));
                                        break;
                                case 1098:
-                                       name = new String(value, Charsets.US_ASCII);
+                                       final String name = new String(value, Charsets.US_ASCII);
+                                       builder.setLinkName(name);
                                        logger.trace("Parsed Link Name : ", name);
                                        break;
                                default:
@@ -577,30 +532,21 @@ public class LinkStateParser {
                                }
                        }
                }
-               state = state.withLocalRouterIdentifiers(localIds);
-               state = state.withRemoteRouterIdentifiers(remoteIds);
-               state = state.withEnabledMPLSProtocols(enabledMPLSProtocols);
-               state = state.withSharedRiskLinkGroups(sharedRiskLinkGroups);
-               state = state.withSymbolicName(name);
-               final NetworkLinkImpl link = new NetworkLinkImpl(linkId, state);
                logger.debug("Finished parsing Link Attributes.");
-               return link;
+               return builder.build();
        }
 
        /**
         * Parse Node Attributes.
         * 
-        * @param descriptors
-        * @param bytes
-        * @return
-        * @throws BGPParsingException
+        * @param attributes key is the tlv type and value is the value of the tlv
+        * @return {@link NodeAttributes}
+        * @throws BGPParsingException if a node attribute is not recognized
         */
-       public static NetworkNodeImpl parseNodeAttributes(final NodeIdentifier nodeId, final Map<Integer, ByteList> attributes)
-                       throws BGPParsingException {
-               final Set<TopologyIdentifier> topologyMembership = Sets.newHashSet();
-               final Set<ISISAreaIdentifier> areaMembership = Sets.newHashSet();
-               final Set<RouterIdentifier> ids = Sets.newHashSet();
-               NetworkNodeState state = NetworkNodeState.EMPTY;
+       public static NodeAttributes parseNodeAttributes(final Map<Integer, ByteList> attributes) throws BGPParsingException {
+               final List<TopologyIdentifier> topologyMembership = Lists.newArrayList();
+               final List<IsisAreaIdentifier> areaMembership = Lists.newArrayList();
+               final NodeAttributesBuilder builder = new NodeAttributesBuilder();
                for (final Entry<Integer, ByteList> entry : attributes.entrySet()) {
                        logger.debug("Node attribute TLV {}", entry.getKey());
                        for (final byte[] value : entry.getValue().getBytes()) {
@@ -608,7 +554,7 @@ public class LinkStateParser {
                                case 263:
                                        int i = 0;
                                        while (i != value.length) {
-                                               final TopologyIdentifier topId = new TopologyIdentifier(ByteArray.bytesToLong(ByteArray.subByte(value, i, 2)) & 0x3fff);
+                                               final TopologyIdentifier topId = new TopologyIdentifier(ByteArray.bytesToInt(ByteArray.subByte(value, i, 2)) & 0x3fff);
                                                topologyMembership.add(topId);
                                                logger.trace("Parsed Topology Identifier: {}", topId);
                                                i += 2;
@@ -616,32 +562,29 @@ public class LinkStateParser {
                                        break;
                                case 1024:
                                        final boolean[] flags = ByteArray.parseBits(value[0]);
-                                       state = state.withOverload(flags[0]);
-                                       state = state.withAttached(flags[1]);
-                                       state = state.withExternal(flags[2]);
-                                       state = state.withAreaBorderRouter(flags[3]);
+                                       builder.setNodeFlags(new NodeFlagBits(flags[0], flags[1], flags[2], flags[3]));
                                        logger.trace("Parsed External bit {}, area border router {}.", flags[2], flags[3]);
                                        break;
                                case 1025:
                                        logger.debug("Ignoring opaque value: {}.", Arrays.toString(value));
                                        break;
                                case 1026:
-                                       state = state.withDynamicHostname(new String(value, Charsets.US_ASCII));
-                                       logger.trace("Parsed Node Name {}", state.getDynamicHostname());
+                                       builder.setDynamicHostname(new String(value, Charsets.US_ASCII));
+                                       logger.trace("Parsed Node Name {}", builder.getDynamicHostname());
                                        break;
                                case 1027:
-                                       final ISISAreaIdentifier ai = new ISISAreaIdentifier(value);
+                                       final IsisAreaIdentifier ai = new IsisAreaIdentifier(value);
                                        areaMembership.add(ai);
                                        logger.trace("Parsed AreaIdentifier {}", ai);
                                        break;
                                case 1028:
-                                       final IPv4RouterIdentifier ip4 = new IPv4RouterIdentifier(new IPv4Address(value));
-                                       ids.add(ip4);
+                                       final Ipv4RouterIdentifier ip4 = new Ipv4RouterIdentifier(Ipv4Util.addressForBytes(value));
+                                       builder.setIpv4RouterId(ip4);
                                        logger.trace("Parsed IPv4 Router Identifier {}", ip4);
                                        break;
                                case 1029:
-                                       final IPv6RouterIdentifier ip6 = new IPv6RouterIdentifier(new IPv6Address(value));
-                                       ids.add(ip6);
+                                       final Ipv6RouterIdentifier ip6 = new Ipv6RouterIdentifier(Ipv6Util.addressForBytes(value));
+                                       builder.setIpv6RouterId(ip6);
                                        logger.trace("Parsed IPv6 Router Identifier {}", ip6);
                                        break;
                                default:
@@ -649,31 +592,31 @@ public class LinkStateParser {
                                }
                        }
                }
-
-               state = state.withAreaMembership(areaMembership);
-               state = state.withIdentifierAlternatives(ids);
-               state = state.withTopologyMembership(topologyMembership);
-               final NetworkNodeImpl node = new NetworkNodeImpl(nodeId, state);
+               builder.setTopologyIdentifier(topologyMembership);
+               builder.setIsisAreaId(areaMembership);
                logger.debug("Finished parsing Node Attributes.");
-               return node;
+               return builder.build();
        }
 
-       public static NetworkPrefixState parsePrefixAttributes(final ProtocolId src, final NetworkObjectState nos,
-                       final Map<Integer, ByteList> attributes) throws BGPParsingException {
-
-               boolean upDownBit = false;
-               final SortedSet<RouteTag> routeTags = Sets.newTreeSet();
-               final SortedSet<ExtendedRouteTag> exRouteTags = Sets.newTreeSet();
-               Metric<?> metric = null;
-               IPv4Address fwdAddress4 = null;
-               IPv6Address fwdAddress6 = null;
+       /**
+        * Parse prefix attributes.
+        * 
+        * @param attributes key is the tlv type and value are the value bytes of the tlv
+        * @return {@link PrefixAttributes}
+        * @throws BGPParsingException if some prefix attributes is not recognized
+        */
+       public static PrefixAttributes parsePrefixAttributes(final Map<Integer, ByteList> attributes) throws BGPParsingException {
+               final PrefixAttributesBuilder builder = new PrefixAttributesBuilder();
+               final List<RouteTag> routeTags = Lists.newArrayList();
+               final List<ExtendedRouteTag> exRouteTags = Lists.newArrayList();
                for (final Entry<Integer, ByteList> entry : attributes.entrySet()) {
                        logger.debug("Prefix attribute TLV {}", entry.getKey());
                        for (final byte[] value : entry.getValue().getBytes()) {
                                switch (entry.getKey()) {
                                case 1152:
                                        final boolean[] flags = ByteArray.parseBits(value[0]);
-                                       upDownBit = flags[2];
+                                       final boolean upDownBit = flags[2];
+                                       builder.setIgpBits(new IgpBitsBuilder().setUpDown(new UpDown(upDownBit)).build());
                                        logger.trace("Parsed IGP flag (up/down bit) : {}", upDownBit);
                                        break;
                                case 1153:
@@ -695,23 +638,23 @@ public class LinkStateParser {
                                        }
                                        break;
                                case 1155:
-                                       metric = new IGPMetric(ByteArray.bytesToLong(value));
+                                       final IgpMetric metric = new IgpMetric(ByteArray.bytesToLong(value));
+                                       builder.setPrefixMetric(metric);
                                        logger.trace("Parsed Metric: {}", metric);
                                        break;
                                case 1156:
+                                       IpAddress fwdAddress = null;
                                        switch (value.length) {
                                        case 4:
-                                               fwdAddress4 = new IPv4Address(value);
-                                               logger.trace("Parsed FWD Address: {}", fwdAddress4);
+                                               fwdAddress = new IpAddress(Ipv4Util.addressForBytes(value));
                                                break;
                                        case 16:
-                                               fwdAddress6 = new IPv6Address(value);
-                                               logger.trace("Parsed FWD Address: {}", fwdAddress6);
+                                               fwdAddress = new IpAddress(Ipv6Util.addressForBytes(value));
                                                break;
                                        default:
                                                logger.debug("Ignoring unsupported forwarding address length {}", value.length);
                                        }
-
+                                       logger.trace("Parsed FWD Address: {}", fwdAddress);
                                        break;
                                case 1157:
                                        final byte[] opaque = value;
@@ -722,71 +665,9 @@ public class LinkStateParser {
                                }
                        }
                }
-
                logger.debug("Finished parsing Prefix Attributes.");
-
-               final NetworkPrefixState nps = new NetworkPrefixState(nos, routeTags, metric);
-               switch (src) {
-               case IsisLevel1:
-               case IsisLevel2:
-                       return new ISISNetworkPrefixState(nps, exRouteTags, upDownBit);
-               case Ospf:
-                       if (fwdAddress4 != null) {
-                               return new OSPFNetworkPrefixState<IPv4Address>(nps, fwdAddress4);
-                       }
-                       if (fwdAddress6 != null) {
-                               return new OSPFNetworkPrefixState<IPv6Address>(nps, fwdAddress6);
-                       }
-                       logger.debug("OSPF-sourced has no forwarding address");
-                       return nps;
-               default:
-                       return nps;
-               }
-       }
-
-       /**
-        * Parse Link Protection Type from int to enum
-        * 
-        * @param type int parsed from byte array
-        * @return enum LinkProtectionType
-        * @throws BGPParsingException if the type is unrecognized
-        */
-       private static LinkProtectionType parseLinkProtectionType(final int type) throws BGPParsingException {
-               switch (type) {
-               case 1:
-                       return LinkProtectionType.EXTRA_TRAFFIC;
-               case 2:
-                       return LinkProtectionType.UNPROTECTED;
-               case 4:
-                       return LinkProtectionType.SHARED;
-               case 8:
-                       return LinkProtectionType.DEDICATED_ONE_TO_ONE;
-               case 16:
-                       return LinkProtectionType.DEDICATED_ONE_PLUS_ONE;
-               default:
-                       throw new BGPParsingException("Link Protection Type not recognized: " + type);
-               }
-       }
-
-       /**
-        * Parse NLRI Type from int to enum
-        * 
-        * @param type int parsed from byte array
-        * @return enum NlriType
-        * @throws BGPParsingException if the type is unrecognized
-        */
-       private static NlriType parseNLRItype(final int type) throws BGPParsingException {
-               switch (type) {
-               case 1:
-                       return NlriType.NodeNLRI;
-               case 2:
-                       return NlriType.LinkNLRI;
-               case 3:
-                       return NlriType.IPv4Prefixes;
-               case 4:
-                       return NlriType.IPv6Prefixes;
-               default:
-                       throw new BGPParsingException("NLRI Type not recognized: " + type);
-               }
+               builder.setRouteTags(routeTags);
+               builder.setExtendedTags(exRouteTags);
+               return builder.build();
        }
 }