BUG-2794: incorporate ofjava instruction changes
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / sal / convertor / FlowConvertor.java
index 8196d3f313345d2516f5d2039e7de0efdabd14b0..6837255dc90b7b8c64e0a0ed40c077fa054705e5 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2013 Ericsson. and others.  All rights reserved.
+ * Copyright (c) 2013-2014 Ericsson. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor;
 
 import java.math.BigInteger;
-import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.openflowplugin.api.OFConstants;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.OrderComparator;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.flowflag.FlowFlagReactor;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchReactor;
+import org.opendaylight.openflowplugin.openflow.md.util.ByteUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.VlanCfi;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.vlan.action._case.PushVlanActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlowBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActions;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTable;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.Meter;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ClearActions;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteActions;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadata;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpSourceHardwareAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpTargetHardwareAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestination;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSource;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Icmpv4Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Icmpv6Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer4Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.ProtocolMatchFields;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ClearActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.MeterCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTable;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.meter._case.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.actions._case.WriteActions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.metadata._case.WriteMetadata;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.SctpMatch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionsInstruction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionsInstructionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.BosMatchEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.BosMatchEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.DscpMatchEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.DscpMatchEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EcnMatchEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EcnMatchEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EthTypeMatchEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EthTypeMatchEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Icmpv4CodeMatchEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Icmpv4CodeMatchEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Icmpv4TypeMatchEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Icmpv4TypeMatchEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Icmpv6CodeMatchEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Icmpv6CodeMatchEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Icmpv6TypeMatchEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Icmpv6TypeMatchEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv4AddressMatchEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv4AddressMatchEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv6AddressMatchEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv6AddressMatchEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv6FlabelMatchEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.IsidMatchEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.IsidMatchEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MacAddressMatchEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MacAddressMatchEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaskMatchEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaskMatchEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataInstruction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataInstructionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataMatchEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataMatchEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MeterIdInstruction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MeterIdInstructionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MplsLabelMatchEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MplsLabelMatchEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OpCodeMatchEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OpCodeMatchEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortMatchEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortMatchEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortNumberMatchEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortNumberMatchEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ProtocolNumberMatchEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ProtocolNumberMatchEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PseudoFieldMatchEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PseudoFieldMatchEntry.PseudoField;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PseudoFieldMatchEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TableIdInstruction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TableIdInstructionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TcMatchEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TcMatchEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanPcpMatchEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanVidMatchEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanVidMatchEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.Instructions;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.InstructionsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.EtherType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.ClearActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.GotoTableCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.MeterCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.WriteActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.WriteMetadataCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice._goto.table._case.GotoTableBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.meter._case.MeterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.write.actions._case.WriteActionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.write.metadata._case.WriteMetadataBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.InstructionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModCommand;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MatchTypeBase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.ArpOp;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.ArpSha;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.ArpSpa;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.ArpTha;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.ArpTpa;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.EthDst;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.EthSrc;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.EthType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Icmpv4Code;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Icmpv4Type;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Icmpv6Code;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Icmpv6Type;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.InPhyPort;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.InPort;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.IpDscp;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.IpProto;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv4Dst;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv4Src;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6Dst;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6Exthdr;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6Flabel;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6NdSll;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6NdTarget;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6NdTll;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6Src;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Metadata;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.MplsBos;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.MplsLabel;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.MplsTc;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OpenflowBasicClass;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.PbbIsid;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.SctpDst;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.SctpSrc;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.TcpDst;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.TcpSrc;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.TunnelId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.UdpDst;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.UdpSrc;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.VlanPcp;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.VlanVid;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntries;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntriesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowMod;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OxmMatchType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.match.grouping.Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.match.grouping.MatchBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.collect.Ordering;
+
 /**
  * Utility class for converting a MD-SAL Flow into the OF flow mod
  */
 public class FlowConvertor {
-    private static final Logger logger = LoggerFactory.getLogger(FlowConvertor.class);
-    private static final String PREFIX_SEPARATOR = "/";
-
-    public static FlowModInput toFlowModInput(Flow flow) {
-        FlowModInputBuilder flowMod = new FlowModInputBuilder();
-
-        flowMod.setCookie(flow.getCookie());
-
-        if (flow.getCookieMask() != null) {
-            flowMod.setCookieMask(new BigInteger(flow.getCookieMask().toString()));
-        }
+    private static final Logger LOG = LoggerFactory.getLogger(FlowConvertor.class);
+
+    // Default values for when things are null
+    private static final TableId DEFAULT_TABLE_ID = new TableId(0L);
+    /**
+     * Default idle timeout
+     */
+    public static final Integer DEFAULT_IDLE_TIMEOUT = 5 * 60;
+    /**
+     * Default hard timeout
+     */
+    public static final Integer DEFAULT_HARD_TIMEOUT = 10 * 60;
+    /**
+     * Default priority
+     */
+    public static final Integer DEFAULT_PRIORITY = Integer.parseInt("8000", 16);
+    private static final Long DEFAULT_BUFFER_ID = OFConstants.OFP_NO_BUFFER;
+    private static final Long OFPP_ANY = Long.parseLong("ffffffff", 16);
+    private static final Long DEFAULT_OUT_PORT = OFPP_ANY;
+    private static final Long OFPG_ANY = Long.parseLong("ffffffff", 16);
+    private static final Long DEFAULT_OUT_GROUP = OFPG_ANY;
+    /**
+     * flow flag: remove
+     */
+    public static final boolean DEFAULT_OFPFF_FLOW_REM = false;
+    /**
+     * flow flag: check overlap
+     */
+    public static final boolean DEFAULT_OFPFF_CHECK_OVERLAP = false;
+    /**
+     * flow flag: reset counts
+     */
+    public static final boolean DEFAULT_OFPFF_RESET_COUNTS = false;
+    /**
+     * flow flag: don't keep track of packet counts
+     */
+    public static final boolean DEFAULT_OFPFF_NO_PKT_COUNTS = false;
+    /**
+     * flow flag: don't keep track of byte counts
+     */
+    public static final boolean DEFAULT_OFPFF_NO_BYT_COUNTS = false;
+    /**
+     * flow flag: emergency [OFP-1.0]
+     */
+    public static final boolean DEFAULT_OFPFF_EMERGENCY = false;
+    /**
+     * OxmMatch type
+     */
+    public static final Class<? extends MatchTypeBase> DEFAULT_MATCH_TYPE = OxmMatchType.class;
+    /**
+     * default match entries - empty
+     */
+    public static final List<MatchEntry> DEFAULT_MATCH_ENTRIES = new ArrayList<MatchEntry>();
+
+
+    private FlowConvertor() {
+        //hiding implicit constructor
+    }
 
-        if (flow.getTableId() != null) {
-            flowMod.setTableId(new TableId(flow.getTableId().longValue()));
+    /**
+     * This method converts the SAL Flow to OF Flow.
+     * It checks if there is a set-vlan-id (1.0) action made on OF1.3.
+     * If yes its handled separately
+     */
+    public static List<FlowModInputBuilder> toFlowModInputs(Flow srcFlow, short version, BigInteger datapathId) {
+        List<FlowModInputBuilder> list = new ArrayList<>();
+
+        if (version >= OFConstants.OFP_VERSION_1_3 && isSetVlanIdActionCasePresent(srcFlow)) {
+            list.addAll(handleSetVlanIdForOF13(srcFlow, version, datapathId));
+        } else {
+            list.add(toFlowModInput(srcFlow, version, datapathId));
         }
+        return list;
+    }
 
-        if (flow instanceof AddFlowInput) {
-            flowMod.setCommand(FlowModCommand.OFPFCADD);
-        } else if (flow instanceof RemoveFlowInput) {
-            if (flow.isStrict()) {
-                flowMod.setCommand(FlowModCommand.OFPFCDELETESTRICT);
-            } else {
-                flowMod.setCommand(FlowModCommand.OFPFCDELETE);
-            }
-        } else if (flow instanceof UpdateFlowInput) {
-            if (flow.isStrict()) {
-                flowMod.setCommand(FlowModCommand.OFPFCMODIFYSTRICT);
-            } else {
-                flowMod.setCommand(FlowModCommand.OFPFCMODIFY);
-            }
-        }
+    public static FlowModInputBuilder toFlowModInput(Flow flow, short version, BigInteger datapathid) {
 
-        flowMod.setIdleTimeout(flow.getIdleTimeout());
-        flowMod.setHardTimeout(flow.getHardTimeout());
-        flowMod.setPriority(flow.getPriority());
-        flowMod.setBufferId(flow.getBufferId());
+        FlowModInputBuilder flowMod = new FlowModInputBuilder();
+        salToOFFlowCookie(flow, flowMod);
+        salToOFFlowCookieMask(flow, flowMod);
+        salToOFFlowTableId(flow, flowMod);
+        salToOFFlowCommand(flow, flowMod);
+        salToOFFlowIdleTimeout(flow, flowMod);
+        salToOFFlowHardTimeout(flow, flowMod);
+        salToOFFlowPriority(flow, flowMod);
+        salToOFFlowBufferId(flow, flowMod);
+        salToOFFlowOutPort(flow, flowMod);
+        salToOFFlowOutGroup(flow, flowMod);
+
+        // convert and inject flowFlags
+        FlowFlagReactor.getInstance().convert(flow.getFlags(), version, flowMod, datapathid);
+
+        // convert and inject match
+        MatchReactor.getInstance().convert(flow.getMatch(), version, flowMod, datapathid);
 
-        if (flow.getOutPort() != null) {
-            flowMod.setOutPort(new PortNumber(flow.getOutPort().longValue()));
+        if (flow.getInstructions() != null) {
+            flowMod.setInstruction(toInstructions(flow, version, datapathid));
+            flowMod.setAction(getActions(version, datapathid, flow));
         }
+        flowMod.setVersion(version);
 
-        flowMod.setOutGroup(flow.getOutGroup());
+        return flowMod;
+    }
 
-        org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowModFlags flowModFlags = flow.getFlags();
-        org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFlags ofFlowModFlags = null;
-        if (flowModFlags != null) {
-            ofFlowModFlags = new org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFlags(
-                    flowModFlags.isCHECKOVERLAP(), flowModFlags.isNOBYTCOUNTS(), flowModFlags.isNOPKTCOUNTS(),
-                    flowModFlags.isRESETCOUNTS(), flowModFlags.isSENDFLOWREM());
+    private static void salToOFFlowOutGroup(Flow flow, FlowModInputBuilder flowMod) {
+        if (flow.getOutGroup() != null) {
+            flowMod.setOutGroup(flow.getOutGroup());
+        } else {
+            flowMod.setOutGroup(DEFAULT_OUT_GROUP);
         }
-        flowMod.setFlags(ofFlowModFlags);
+    }
 
-        if (flow.getMatch() != null) {
-            flowMod.setMatch(toMatch(flow.getMatch()));
+    private static void salToOFFlowOutPort(Flow flow, FlowModInputBuilder flowMod) {
+        if (flow.getOutPort() != null) {
+            flowMod.setOutPort(new PortNumber(flow.getOutPort().longValue()));
+        } else {
+            flowMod.setOutPort(new PortNumber(DEFAULT_OUT_PORT));
         }
+    }
 
-        if (flow.getInstructions() != null) {
-            flowMod.setInstructions(toInstructions(flow.getInstructions()));
+    private static void salToOFFlowBufferId(Flow flow, FlowModInputBuilder flowMod) {
+        if (flow.getBufferId() != null) {
+            flowMod.setBufferId(flow.getBufferId());
+        } else {
+            flowMod.setBufferId(DEFAULT_BUFFER_ID);
         }
-
-        return flowMod.build();
     }
 
-    public static Match toMatch(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match match) {
-
-        MatchEntriesBuilder matchEntriesBuilder = new MatchEntriesBuilder();
-        MatchBuilder matchBuilder = new MatchBuilder();
-        List<MatchEntries> matchEntriesList = new ArrayList<>();
-
-        if (match.getInPort() != null) {
-            matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-            matchEntriesBuilder.setHasMask(false);
-            matchEntriesBuilder.setOxmMatchField(InPort.class);
-            PortNumberMatchEntryBuilder port = new PortNumberMatchEntryBuilder();
-            port.setPortNumber(new PortNumber(match.getInPort()));
-            matchEntriesBuilder.addAugmentation(PortNumberMatchEntry.class, port.build());
-            matchEntriesList.add(matchEntriesBuilder.build());
+    private static void salToOFFlowPriority(Flow flow, FlowModInputBuilder flowMod) {
+        if (flow.getPriority() != null) {
+            flowMod.setPriority(flow.getPriority());
+        } else {
+            flowMod.setPriority(DEFAULT_PRIORITY);
         }
+    }
 
-        if (match.getInPhyPort() != null) {
-            matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-            matchEntriesBuilder.setHasMask(false);
-            matchEntriesBuilder.setOxmMatchField(InPhyPort.class);
-            PortNumberMatchEntryBuilder phyPort = new PortNumberMatchEntryBuilder();
-            phyPort.setPortNumber(new PortNumber(match.getInPhyPort()));
-            matchEntriesBuilder.addAugmentation(PortNumberMatchEntry.class, phyPort.build());
-            matchEntriesList.add(matchEntriesBuilder.build());
+    private static void salToOFFlowHardTimeout(Flow flow, FlowModInputBuilder flowMod) {
+        if (flow.getHardTimeout() != null) {
+            flowMod.setHardTimeout(flow.getHardTimeout());
+        } else {
+            flowMod.setHardTimeout(DEFAULT_HARD_TIMEOUT);
         }
+    }
 
-        if (match.getMetadata() != null) {
-            matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-            matchEntriesBuilder.setHasMask(false);
-            matchEntriesBuilder.setOxmMatchField(Metadata.class);
-            addMetadataAugmentation(matchEntriesBuilder, match.getMetadata().getMetadata());
-            if (match.getMetadata().getMetadataMask() != null) {
-                addMaskAugmentation(matchEntriesBuilder, match.getMetadata().getMetadataMask());
-            }
-            matchEntriesList.add(matchEntriesBuilder.build());
+    private static void salToOFFlowIdleTimeout(Flow flow, FlowModInputBuilder flowMod) {
+        if (flow.getIdleTimeout() != null) {
+            flowMod.setIdleTimeout(flow.getIdleTimeout());
+        } else {
+            flowMod.setIdleTimeout(DEFAULT_IDLE_TIMEOUT);
         }
+    }
 
-        if (match.getEthernetMatch() != null) {
-            EthernetMatch ethernetMatch = match.getEthernetMatch();
-            EthernetDestination ethernetDestination = ethernetMatch.getEthernetDestination();
-            if (ethernetDestination != null) {
-                matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                matchEntriesBuilder.setHasMask(false);
-                matchEntriesBuilder.setOxmMatchField(EthDst.class);
-                addMacAddressAugmentation(matchEntriesBuilder, ethernetDestination.getAddress());
-                if (ethernetDestination.getMask() != null) {
-                    addMaskAugmentation(matchEntriesBuilder, ethernetDestination.getMask());
-                }
-                matchEntriesList.add(matchEntriesBuilder.build());
-            }
-
-            EthernetSource ethernetSource = ethernetMatch.getEthernetSource();
-            if (ethernetSource != null) {
-                matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                matchEntriesBuilder.setHasMask(false);
-                matchEntriesBuilder.setOxmMatchField(EthSrc.class);
-                addMacAddressAugmentation(matchEntriesBuilder, ethernetSource.getAddress());
-                if (ethernetSource.getMask() != null) {
-                    addMaskAugmentation(matchEntriesBuilder, ethernetSource.getMask());
-                }
-                matchEntriesList.add(matchEntriesBuilder.build());
+    private static void salToOFFlowCommand(Flow flow, FlowModInputBuilder flowMod) {
+        if (flow instanceof AddFlowInput) {
+            flowMod.setCommand(FlowModCommand.OFPFCADD);
+        } else if (flow instanceof RemoveFlowInput) {
+            if (Objects.firstNonNull(flow.isStrict(), Boolean.FALSE)) {
+                flowMod.setCommand(FlowModCommand.OFPFCDELETESTRICT);
+            } else {
+                flowMod.setCommand(FlowModCommand.OFPFCDELETE);
             }
-
-            if (ethernetMatch.getEthernetType() != null) {
-                matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                matchEntriesBuilder.setHasMask(false);
-                matchEntriesBuilder.setOxmMatchField(EthType.class);
-                EthTypeMatchEntryBuilder ethertypeBuilder = new EthTypeMatchEntryBuilder();
-                ethertypeBuilder.setEthType(new EtherType(ethernetMatch.getEthernetType().getType().getValue()
-                        .intValue()));
-                matchEntriesBuilder.addAugmentation(EthTypeMatchEntry.class, ethertypeBuilder.build());
-                matchEntriesList.add(matchEntriesBuilder.build());
+        } else if (flow instanceof UpdatedFlow) {
+            if (Objects.firstNonNull(flow.isStrict(), Boolean.FALSE)) {
+                flowMod.setCommand(FlowModCommand.OFPFCMODIFYSTRICT);
+            } else {
+                flowMod.setCommand(FlowModCommand.OFPFCMODIFY);
             }
         }
+    }
 
-        VlanMatch vlanMatch = match.getVlanMatch();
-        if (vlanMatch != null) {
-            if (vlanMatch.getVlanId() != null) {
-                // verify
-                matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                matchEntriesBuilder.setHasMask(true);
-                matchEntriesBuilder.setOxmMatchField(VlanVid.class);
-                VlanVidMatchEntryBuilder vlanVidBuilder = new VlanVidMatchEntryBuilder();
-                Integer vidEntryValue = vlanMatch.getVlanId().getVlanId().getValue();
-                vlanVidBuilder.setCfiBit(vidEntryValue != 0);
-                vlanVidBuilder.setVlanVid(vidEntryValue);
-                matchEntriesBuilder.addAugmentation(VlanVidMatchEntry.class, vlanVidBuilder.build());
-                if (vlanMatch.getVlanId().getMask() != null) {
-                    addMaskAugmentation(matchEntriesBuilder, vlanMatch.getVlanId().getMask());
-                }
-                matchEntriesList.add(matchEntriesBuilder.build());
-            }
+    private static void salToOFFlowTableId(Flow flow, FlowModInputBuilder flowMod) {
+        if (flow.getTableId() != null) {
+            flowMod.setTableId(new TableId(flow.getTableId().longValue()));
+        } else {
+            flowMod.setTableId(DEFAULT_TABLE_ID);
+        }
+    }
 
-            if (vlanMatch.getVlanPcp() != null) {
-                matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                matchEntriesBuilder.setHasMask(false);
-                matchEntriesBuilder.setOxmMatchField(VlanPcp.class);
-                VlanPcpMatchEntryBuilder vlanPcpBuilder = new VlanPcpMatchEntryBuilder();
-                vlanPcpBuilder.setVlanPcp(vlanMatch.getVlanPcp().getValue());
-                matchEntriesBuilder.addAugmentation(VlanVidMatchEntry.class, vlanPcpBuilder.build());
-                matchEntriesList.add(matchEntriesBuilder.build());
-            }
+    private static void salToOFFlowCookieMask(Flow flow, FlowModInputBuilder flowMod) {
+        if (flow.getCookieMask() != null) {
+            flowMod.setCookieMask(flow.getCookieMask().getValue());
+        } else {
+            flowMod.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
         }
+    }
 
-        IpMatch ipMatch = match.getIpMatch();
-        if (ipMatch != null) {
-            if (ipMatch.getIpDscp() != null) {
-                matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                matchEntriesBuilder.setHasMask(false);
-                matchEntriesBuilder.setOxmMatchField(IpDscp.class);
-                DscpMatchEntryBuilder dscpBuilder = new DscpMatchEntryBuilder();
-                dscpBuilder.setDscp(ipMatch.getIpDscp());
-                matchEntriesBuilder.addAugmentation(DscpMatchEntry.class, dscpBuilder.build());
-                matchEntriesList.add(matchEntriesBuilder.build());
-            }
+    private static void salToOFFlowCookie(Flow flow, FlowModInputBuilder flowMod) {
+        if (flow.getCookie() != null) {
+            flowMod.setCookie(flow.getCookie().getValue());
+        } else {
+            flowMod.setCookie(OFConstants.DEFAULT_COOKIE);
+        }
+    }
 
-            if (ipMatch.getIpEcn() != null) {
-                matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                matchEntriesBuilder.setHasMask(false);
-                matchEntriesBuilder.setOxmMatchField(IpDscp.class);
-                EcnMatchEntryBuilder ecnBuilder = new EcnMatchEntryBuilder();
-                ecnBuilder.setEcn(ipMatch.getIpEcn());
-                matchEntriesBuilder.addAugmentation(EcnMatchEntry.class, ecnBuilder.build());
-                matchEntriesList.add(matchEntriesBuilder.build());
-            }
+    private static List<Instruction> toInstructions(
+            Flow flow,
+            short version, BigInteger datapathid) {
+        List<Instruction> instructionsList = new ArrayList<>();
 
-            if (ipMatch.getIpProto() != null) {
-                matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                matchEntriesBuilder.setHasMask(false);
-                matchEntriesBuilder.setOxmMatchField(IpProto.class);
-                ProtocolNumberMatchEntryBuilder protoNumberBuilder = new ProtocolNumberMatchEntryBuilder();
-                protoNumberBuilder.setProtocolNumber((short) ipMatch.getIpProto().getIntValue());
-                matchEntriesBuilder.addAugmentation(ProtocolNumberMatchEntry.class, protoNumberBuilder.build());
-                matchEntriesList.add(matchEntriesBuilder.build());
+        org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions instructions = flow.getInstructions();
+        for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction instruction : instructions
+                .getInstruction()) {
+            InstructionBuilder instructionBuilder = new InstructionBuilder();
+            org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction curInstruction = instruction
+                    .getInstruction();
+            if (curInstruction instanceof GoToTableCase) {
+                GoToTableCase goToTablecase = (GoToTableCase) curInstruction;
+                GoToTable goToTable = goToTablecase.getGoToTable();
+                GotoTableCaseBuilder gotoTableCaseBuilder = new GotoTableCaseBuilder();
+                GotoTableBuilder gotoTableBuilder = new GotoTableBuilder();
+                gotoTableBuilder.setTableId(goToTable.getTableId());
+                gotoTableCaseBuilder.setGotoTable(gotoTableBuilder.build());
+                instructionBuilder.setInstructionChoice(gotoTableCaseBuilder.build());
+                instructionsList.add(instructionBuilder.build());
+            } else if (curInstruction instanceof WriteMetadataCase) {
+                WriteMetadataCase writeMetadatacase = (WriteMetadataCase) curInstruction;
+                WriteMetadata writeMetadata = writeMetadatacase.getWriteMetadata();
+                
+                WriteMetadataCaseBuilder writeMetadataCaseBuilder = new WriteMetadataCaseBuilder();
+                WriteMetadataBuilder writeMetadataBuilder = new WriteMetadataBuilder();
+                writeMetadataBuilder.setMetadata(ByteUtil.convertBigIntegerToNBytes(writeMetadata.getMetadata(),
+                                                                             OFConstants.SIZE_OF_LONG_IN_BYTES));
+                writeMetadataBuilder.setMetadataMask(ByteUtil.convertBigIntegerToNBytes(writeMetadata.getMetadataMask(),
+                                                                                     OFConstants.SIZE_OF_LONG_IN_BYTES));
+                writeMetadataCaseBuilder.setWriteMetadata(writeMetadataBuilder.build());
+                instructionBuilder.setInstructionChoice(writeMetadataCaseBuilder.build());
+                instructionsList.add(instructionBuilder.build());
+            } else if (curInstruction instanceof WriteActionsCase) {
+                WriteActionsCase writeActionscase = (WriteActionsCase) curInstruction;
+                WriteActions writeActions = writeActionscase.getWriteActions();
+                WriteActionsCaseBuilder writeActionsCaseBuilder = new WriteActionsCaseBuilder();
+                WriteActionsBuilder writeActionsBuilder = new WriteActionsBuilder();
+                writeActionsBuilder.setAction(ActionConvertor.getActions(writeActions.getAction(),version, datapathid, flow));
+                writeActionsCaseBuilder.setWriteActions(writeActionsBuilder.build());
+                instructionBuilder.setInstructionChoice(writeActionsCaseBuilder.build());
+                instructionsList.add(instructionBuilder.build());
+            } else if (curInstruction instanceof ApplyActionsCase) {
+                ApplyActionsCase applyActionscase = (ApplyActionsCase) curInstruction;
+                ApplyActions applyActions = applyActionscase.getApplyActions();
+                org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.ApplyActionsCaseBuilder applyActionsCaseBuilder = 
+                        new org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.ApplyActionsCaseBuilder();
+                org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.apply.actions._case.ApplyActionsBuilder applyActionsBuilder = 
+                        new org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.apply.actions._case.ApplyActionsBuilder();
+                applyActionsBuilder.setAction(ActionConvertor.getActions(applyActions.getAction(), version, datapathid, flow));
+                applyActionsCaseBuilder.setApplyActions(applyActionsBuilder.build());
+                instructionBuilder.setInstructionChoice(applyActionsCaseBuilder.build());
+                instructionsList.add(instructionBuilder.build());
+            } else if (curInstruction instanceof ClearActionsCase) {
+                ClearActionsCaseBuilder clearActionsCaseBuilder = new ClearActionsCaseBuilder();  
+                instructionBuilder.setInstructionChoice(clearActionsCaseBuilder.build());
+                instructionsList.add(instructionBuilder.build());
+            } else if (curInstruction instanceof MeterCase) {
+                MeterCase metercase = (MeterCase) curInstruction;
+                Meter meter = metercase.getMeter();
+                MeterCaseBuilder meterCaseBuilder = new MeterCaseBuilder();
+                MeterBuilder meterBuilder = new MeterBuilder();
+                Long meterId = meter.getMeterId().getValue();
+                meterBuilder.setMeterId(meterId);
+                meterCaseBuilder.setMeter(meterBuilder.build());
+                instructionBuilder.setInstructionChoice(meterCaseBuilder.build());
+                instructionsList.add(instructionBuilder.build());
             }
-
         }
+        return instructionsList;
+    }
 
-        Layer4Match layer4Match = match.getLayer4Match();
-        if (layer4Match != null) {
-            if (layer4Match instanceof TcpMatch) {
-                TcpMatch tcpMatch = (TcpMatch) layer4Match;
-                if (tcpMatch.getTcpSourcePort() != null) {
-                    matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                    matchEntriesBuilder.setHasMask(false);
-                    matchEntriesBuilder.setOxmMatchField(TcpSrc.class);
-                    addPortAugmentation(matchEntriesBuilder, tcpMatch.getTcpSourcePort());
-                    matchEntriesList.add(matchEntriesBuilder.build());
-                }
+    private static List<Action> getActions(short version, BigInteger datapathid, Flow flow) {
 
-                if (tcpMatch.getTcpDestinationPort() != null) {
-                    matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                    matchEntriesBuilder.setHasMask(false);
-                    matchEntriesBuilder.setOxmMatchField(TcpDst.class);
-                    addPortAugmentation(matchEntriesBuilder, tcpMatch.getTcpDestinationPort());
-                    matchEntriesList.add(matchEntriesBuilder.build());
-                }
-            }
+        org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions instructions = flow.getInstructions();
+        List<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction> sortedInstructions =
+                Ordering.from(OrderComparator.<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction>build())
+                        .sortedCopy(instructions.getInstruction());
 
-            else if (layer4Match instanceof UdpMatch) {
-                UdpMatch udpMatch = (UdpMatch) layer4Match;
-                if (udpMatch.getUdpSourcePort() != null) {
-                    matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                    matchEntriesBuilder.setHasMask(false);
-                    matchEntriesBuilder.setOxmMatchField(UdpSrc.class);
-                    addPortAugmentation(matchEntriesBuilder, udpMatch.getUdpSourcePort());
-                    matchEntriesList.add(matchEntriesBuilder.build());
-                }
+        for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction instruction : sortedInstructions) {
+            org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction curInstruction = instruction
+                    .getInstruction();
 
-                if (udpMatch.getUdpDestinationPort() != null) {
-                    matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                    matchEntriesBuilder.setHasMask(false);
-                    matchEntriesBuilder.setOxmMatchField(UdpDst.class);
-                    addPortAugmentation(matchEntriesBuilder, udpMatch.getUdpDestinationPort());
-                    matchEntriesList.add(matchEntriesBuilder.build());
-                }
+            if (curInstruction instanceof ApplyActionsCase) {
+                ApplyActionsCase applyActionscase = (ApplyActionsCase) curInstruction;
+                ApplyActions applyActions = applyActionscase.getApplyActions();
+                return ActionConvertor.getActions(applyActions.getAction(), version, datapathid, flow);
             }
+        }
+        return null;
+    }
 
-            else if (layer4Match instanceof SctpMatch) {
-                SctpMatch sctpMatch = (SctpMatch) layer4Match;
-                if (sctpMatch.getSctpSourcePort() != null) {
-                    matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                    matchEntriesBuilder.setHasMask(false);
-                    matchEntriesBuilder.setOxmMatchField(SctpSrc.class);
-                    addPortAugmentation(matchEntriesBuilder, sctpMatch.getSctpSourcePort());
-                    matchEntriesList.add(matchEntriesBuilder.build());
-                }
-
-                if (sctpMatch.getSctpDestinationPort() != null) {
-                    matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                    matchEntriesBuilder.setHasMask(false);
-                    matchEntriesBuilder.setOxmMatchField(SctpDst.class);
-                    addPortAugmentation(matchEntriesBuilder, sctpMatch.getSctpDestinationPort());
-                    matchEntriesList.add(matchEntriesBuilder.build());
+    // check if set vlanid action is present in the flow
+    private static boolean isSetVlanIdActionCasePresent(Flow flow) {
+        boolean isPresent = false;
+        // we are trying to find if there is a set-vlan-id action (OF1.0) action present in the flow.
+        // If yes,then we would need to two flows
+        if (flow.getInstructions() != null) {
+            for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction instruction :
+                    flow.getInstructions().getInstruction()) {
+                org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction curInstruction =
+                        instruction.getInstruction();
+
+                if (curInstruction instanceof ApplyActionsCase) {
+                    ApplyActionsCase applyActionscase = (ApplyActionsCase) curInstruction;
+                    ApplyActions applyActions = applyActionscase.getApplyActions();
+                    for (org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action action :
+                            applyActions.getAction()) {
+                        if (action.getAction() instanceof SetVlanIdActionCase) {
+                            isPresent = true;
+                            break;
+                        }
+                    }
                 }
             }
         }
+        return isPresent;
+    }
 
-        Icmpv4Match icmpv4Match = match.getIcmpv4Match();
-        if (icmpv4Match != null) {
-            if (icmpv4Match.getIcmpv4Type() != null) {
-                matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                matchEntriesBuilder.setHasMask(false);
-                matchEntriesBuilder.setOxmMatchField(Icmpv4Type.class);
-                Icmpv4TypeMatchEntryBuilder icmpv4TypeBuilder = new Icmpv4TypeMatchEntryBuilder();
-                icmpv4TypeBuilder.setIcmpv4Type(icmpv4Match.getIcmpv4Type());
-                matchEntriesBuilder.addAugmentation(Icmpv4TypeMatchEntry.class, icmpv4TypeBuilder.build());
-                matchEntriesList.add(matchEntriesBuilder.build());
-            }
 
-            if (icmpv4Match.getIcmpv4Code() != null) {
-                matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                matchEntriesBuilder.setHasMask(false);
-                matchEntriesBuilder.setOxmMatchField(Icmpv4Code.class);
-                Icmpv4CodeMatchEntryBuilder icmpv4CodeBuilder = new Icmpv4CodeMatchEntryBuilder();
-                icmpv4CodeBuilder.setIcmpv4Code(icmpv4Match.getIcmpv4Code());
-                matchEntriesBuilder.addAugmentation(Icmpv4CodeMatchEntry.class, icmpv4CodeBuilder.build());
-                matchEntriesList.add(matchEntriesBuilder.build());
+    /**
+     * A) If user provided flow's match includes vlan match Â and action has set_vlan_field
+     * Install following rules
+     * Â  Â 1) match on (OFPVID_PRESENT |value) without mask + action [set_field]
+     * <p/>
+     * B) if user provided flow's match doesn't include vlan match but action has set_vlan field
+     * Â  Â  1) Match on (OFPVID_NONE ) without mask + action [push vlan tag + set_field]
+     * Â  Â  2) Match on (OFPVID_PRESENT) with mask (OFPVID_PRESENT ) + action [ set_field]
+     */
+    private static List<FlowModInputBuilder> handleSetVlanIdForOF13(Flow srcFlow, short version, BigInteger datapathId) {
+        List<FlowModInputBuilder> list = new ArrayList<>();
+
+        VlanMatch srcVlanMatch = srcFlow.getMatch().getVlanMatch();
+        boolean hasVlanMatch = (srcFlow.getMatch() != null && srcVlanMatch != null);
+        if (hasVlanMatch) {
+            //create flow with setfield and match
+            // match on vlan tag or vlanid with no mask
+            VlanMatchBuilder vlanMatchBuilder = new VlanMatchBuilder(srcVlanMatch);
+            VlanIdBuilder vlanIdBuilder = new VlanIdBuilder();
+            vlanIdBuilder.setVlanIdPresent(srcVlanMatch.getVlanId().isVlanIdPresent());
+            vlanIdBuilder.setVlanId(srcVlanMatch.getVlanId().getVlanId());
+            vlanMatchBuilder.setVlanId(vlanIdBuilder.build());
+            Match match = new MatchBuilder(srcFlow.getMatch()).setVlanMatch(vlanMatchBuilder.build()).build();
+
+            Optional<? extends Flow> optional = injectMatchToFlow(srcFlow, match);
+            if (optional.isPresent()) {
+                list.add(toFlowModInput(optional.get(), version, datapathId));
+            }
+        } else {
+            // create 2 flows
+            //flow 1
+            // match on no vlan tag with no mask
+            VlanMatchBuilder vlanMatchBuilder = new VlanMatchBuilder();
+            VlanIdBuilder vlanIdBuilder = new VlanIdBuilder();
+            vlanIdBuilder.setVlanIdPresent(false);
+            vlanIdBuilder.setVlanId(new VlanId(0));
+            vlanMatchBuilder.setVlanId(vlanIdBuilder.build());
+            Match match1 = new MatchBuilder(srcFlow.getMatch()).setVlanMatch(vlanMatchBuilder.build()).build();
+
+            Optional<? extends Flow> optional1 = injectMatchAndAction(srcFlow, match1);
+            if (optional1.isPresent()) {
+                list.add(toFlowModInput(optional1.get(), version, datapathId));
+            }
+
+            //flow2
+            // match on vlan tag with mask
+            VlanMatchBuilder vlanMatchBuilder2 = new VlanMatchBuilder();
+            VlanIdBuilder vlanIdBuilder2 = new VlanIdBuilder();
+            vlanIdBuilder2.setVlanIdPresent(true);
+            vlanIdBuilder2.setVlanId(new VlanId(0));
+            vlanMatchBuilder2.setVlanId(vlanIdBuilder2.build());
+            Match match2 = new MatchBuilder(srcFlow.getMatch()).setVlanMatch(vlanMatchBuilder2.build()).build();
+            Optional<? extends Flow> optional2 = injectMatchToFlow(srcFlow, match2);
+            if (optional2.isPresent()) {
+                list.add(toFlowModInput(optional2.get(), version, datapathId));
             }
         }
+        return list;
+    }
 
-        Icmpv6Match icmpv6Match = match.getIcmpv6Match();
-        if (icmpv6Match != null) {
-            if (icmpv6Match.getIcmpv6Type() != null) {
-                matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                matchEntriesBuilder.setHasMask(false);
-                matchEntriesBuilder.setOxmMatchField(Icmpv6Type.class);
-                Icmpv6TypeMatchEntryBuilder icmpv6TypeBuilder = new Icmpv6TypeMatchEntryBuilder();
-                icmpv6TypeBuilder.setIcmpv6Type(icmpv6Match.getIcmpv6Type());
-                matchEntriesBuilder.addAugmentation(Icmpv6TypeMatchEntry.class, icmpv6TypeBuilder.build());
-                matchEntriesList.add(matchEntriesBuilder.build());
-            }
 
-            if (icmpv6Match.getIcmpv6Code() != null) {
-                matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                matchEntriesBuilder.setHasMask(false);
-                matchEntriesBuilder.setOxmMatchField(Icmpv6Code.class);
-                Icmpv6CodeMatchEntryBuilder icmpv6CodeBuilder = new Icmpv6CodeMatchEntryBuilder();
-                icmpv6CodeBuilder.setIcmpv6Code(icmpv6Match.getIcmpv6Code());
-                matchEntriesBuilder.addAugmentation(Icmpv6CodeMatchEntry.class, icmpv6CodeBuilder.build());
-                matchEntriesList.add(matchEntriesBuilder.build());
-            }
+    private static Optional<? extends Flow> injectMatchToFlow(Flow sourceFlow, Match match) {
+        if (sourceFlow instanceof AddFlowInput) {
+            return Optional.<AddFlowInput>of(new AddFlowInputBuilder(sourceFlow).setMatch(match).build());
+        } else if (sourceFlow instanceof RemoveFlowInput) {
+            return Optional.<RemoveFlowInput>of(new RemoveFlowInputBuilder(sourceFlow).setMatch(match).build());
+        } else if (sourceFlow instanceof UpdatedFlow) {
+            return Optional.<UpdatedFlow>of(new UpdatedFlowBuilder(sourceFlow).setMatch(match).build());
+        } else {
+            return Optional.<Flow>absent();
         }
+    }
 
-        Layer3Match layer3Match = match.getLayer3Match();
-        if (layer3Match != null) {
-            if (layer3Match instanceof Ipv4Match) {
-                Ipv4Match ipv4Match = (Ipv4Match) layer3Match;
-                if (ipv4Match.getIpv4Source() != null) {
-                    matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                    matchEntriesBuilder.setHasMask(false);
-                    matchEntriesBuilder.setOxmMatchField(Ipv4Src.class);
-                    addIpv4PrefixAugmentation(matchEntriesBuilder, ipv4Match.getIpv4Source());
-                    matchEntriesList.add(matchEntriesBuilder.build());
-                }
-                if (ipv4Match.getIpv4Destination() != null) {
-                    matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                    matchEntriesBuilder.setHasMask(false);
-                    matchEntriesBuilder.setOxmMatchField(Ipv4Dst.class);
-                    addIpv4PrefixAugmentation(matchEntriesBuilder, ipv4Match.getIpv4Destination());
-                    matchEntriesList.add(matchEntriesBuilder.build());
-                }
-            }
+    private static Optional<? extends Flow> injectMatchAndAction(Flow sourceFlow, Match match) {
+
+        Instructions instructions = (new InstructionsBuilder())
+                .setInstruction(injectPushActionToInstruction(sourceFlow))
+                .build();
+
+        if (sourceFlow instanceof AddFlowInput) {
+            return Optional.<AddFlowInput>of(new AddFlowInputBuilder(sourceFlow)
+                    .setMatch(match).setInstructions(instructions).build());
+        } else if (sourceFlow instanceof RemoveFlowInput) {
+            return Optional.<RemoveFlowInput>of(new RemoveFlowInputBuilder(sourceFlow)
+                    .setMatch(match).setInstructions(instructions).build());
+        } else if (sourceFlow instanceof UpdatedFlow) {
+            return Optional.<UpdatedFlow>of(new UpdatedFlowBuilder(sourceFlow)
+                    .setMatch(match).setInstructions(instructions).build());
+        } else {
+            return Optional.<Flow>absent();
+        }
+    }
 
-            else if (layer3Match instanceof ArpMatch) {
-                ArpMatch arpMatch = (ArpMatch) layer3Match;
-                if (arpMatch.getArpOp() != null) {
-                    matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                    matchEntriesBuilder.setHasMask(false);
-                    matchEntriesBuilder.setOxmMatchField(ArpOp.class);
-                    OpCodeMatchEntryBuilder opcodeBuilder = new OpCodeMatchEntryBuilder();
-                    opcodeBuilder.setOpCode(arpMatch.getArpOp());
-                    matchEntriesBuilder.addAugmentation(OpCodeMatchEntry.class, opcodeBuilder.build());
-                    matchEntriesList.add(matchEntriesBuilder.build());
-                }
+    private static List<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction>
+    injectPushActionToInstruction(final Flow sourceFlow) {
 
-                if (arpMatch.getArpSourceTransportAddress() != null) {
-                    matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                    matchEntriesBuilder.setHasMask(false);
-                    matchEntriesBuilder.setOxmMatchField(ArpSpa.class);
-                    addIpv4PrefixAugmentation(matchEntriesBuilder, arpMatch.getArpSourceTransportAddress());
-                    matchEntriesList.add(matchEntriesBuilder.build());
-                }
+        List<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction> srcInstructionList =
+                sourceFlow.getInstructions().getInstruction();
 
-                if (arpMatch.getArpTargetTransportAddress() != null) {
-                    matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                    matchEntriesBuilder.setHasMask(false);
-                    matchEntriesBuilder.setOxmMatchField(ArpTpa.class);
-                    addIpv4PrefixAugmentation(matchEntriesBuilder, arpMatch.getArpTargetTransportAddress());
-                    matchEntriesList.add(matchEntriesBuilder.build());
-                }
+        List<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction> targetInstructionList = new ArrayList<>(srcInstructionList.size());
+        List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> targetActionList = new ArrayList<>();
 
-                ArpSourceHardwareAddress arpSourceHardwareAddress = arpMatch.getArpSourceHardwareAddress();
-                if (arpSourceHardwareAddress != null) {
-                    matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                    matchEntriesBuilder.setHasMask(false);
-                    matchEntriesBuilder.setOxmMatchField(ArpSha.class);
-                    addMacAddressAugmentation(matchEntriesBuilder, arpSourceHardwareAddress.getAddress());
-                    if (arpSourceHardwareAddress.getMask() != null) {
-                        addMaskAugmentation(matchEntriesBuilder, arpSourceHardwareAddress.getMask());
-                    }
-                    matchEntriesList.add(matchEntriesBuilder.build());
-                }
+        org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder instructionBuilder =
+                new org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder();
 
-                ArpTargetHardwareAddress arpTargetHardwareAddress = arpMatch.getArpTargetHardwareAddress();
-                if (arpTargetHardwareAddress != null) {
-                    matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                    matchEntriesBuilder.setHasMask(false);
-                    matchEntriesBuilder.setOxmMatchField(ArpTha.class);
-                    addMacAddressAugmentation(matchEntriesBuilder, arpTargetHardwareAddress.getAddress());
-                    if (arpTargetHardwareAddress.getMask() != null) {
-                        addMaskAugmentation(matchEntriesBuilder, arpTargetHardwareAddress.getMask());
-                    }
-                    matchEntriesList.add(matchEntriesBuilder.build());
-                }
-            }
+        for (int i = 0; i < srcInstructionList.size(); i++) {
+            org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction srcInstruction =
+                    srcInstructionList.get(i);
+            org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction curSrcInstruction =
+                    srcInstruction.getInstruction();
 
-            else if (layer3Match instanceof Ipv6Match) {
-                Ipv6Match ipv6Match = (Ipv6Match) layer3Match;
-                if (ipv6Match.getIpv6Source() != null) {
-                    matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                    matchEntriesBuilder.setHasMask(false);
-                    matchEntriesBuilder.setOxmMatchField(Ipv6Src.class);
-                    addIpv6PrefixAugmentation(matchEntriesBuilder, ipv6Match.getIpv6Source());
-                    matchEntriesList.add(matchEntriesBuilder.build());
-                }
+            if (curSrcInstruction instanceof ApplyActionsCase) {
+                ApplyActionsCase applyActionscase = (ApplyActionsCase) curSrcInstruction;
+                ApplyActions applyActions = applyActionscase.getApplyActions();
+                List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> srcActionList = applyActions.getAction();
 
-                if (ipv6Match.getIpv6Destination() != null) {
-                    matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                    matchEntriesBuilder.setHasMask(false);
-                    matchEntriesBuilder.setOxmMatchField(Ipv6Dst.class);
-                    addIpv6PrefixAugmentation(matchEntriesBuilder, ipv6Match.getIpv6Destination());
-                    matchEntriesList.add(matchEntriesBuilder.build());
-                }
+                int offset = 0;
+                for (int j = 0; j < srcActionList.size(); j++) {
+                    // check if its a set-vlan-action. If yes, then add the injected-action
 
-                if (ipv6Match.getIpv6Label() != null) {
-                    // verify
-                    matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                    matchEntriesBuilder.setHasMask(false);
-                    matchEntriesBuilder.setOxmMatchField(Ipv6Flabel.class);
-                    Ipv6FlabelMatchEntryBuilder ipv6FlabelBuilder = new Ipv6FlabelMatchEntryBuilder();
-                    ipv6FlabelBuilder.setIpv6Flabel(ipv6Match.getIpv6Label().getIpv6Flabel());
-                    if (ipv6Match.getIpv6Label().getFlabelMask() != null) {
-                        addMaskAugmentation(matchEntriesBuilder, ipv6Match.getIpv6Label().getFlabelMask());
-                    }
-                    matchEntriesList.add(matchEntriesBuilder.build());
-                }
+                    org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action actionItem = srcActionList.get(j);
+                    if (actionItem.getAction() instanceof SetVlanIdActionCase) {
+                        SetVlanIdActionCase setVlanIdActionCase = (SetVlanIdActionCase) actionItem.getAction();
 
-                if (ipv6Match.getIpv6NdTarget() != null) {
-                    matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                    matchEntriesBuilder.setHasMask(false);
-                    matchEntriesBuilder.setOxmMatchField(Ipv6NdTarget.class);
-                    addIpv6AddressAugmentation(matchEntriesBuilder, ipv6Match.getIpv6NdTarget());
-                    matchEntriesList.add(matchEntriesBuilder.build());
-                }
+                        PushVlanActionCaseBuilder pushVlanActionCaseBuilder = new PushVlanActionCaseBuilder();
+                        PushVlanActionBuilder pushVlanActionBuilder = new PushVlanActionBuilder();
 
-                if (ipv6Match.getIpv6NdSll() != null) {
-                    matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                    matchEntriesBuilder.setHasMask(false);
-                    matchEntriesBuilder.setOxmMatchField(Ipv6NdSll.class);
-                    addMacAddressAugmentation(matchEntriesBuilder, ipv6Match.getIpv6NdSll());
-                    matchEntriesList.add(matchEntriesBuilder.build());
-                }
+                        pushVlanActionBuilder.setCfi(new VlanCfi(1))
+                                .setVlanId(setVlanIdActionCase.getSetVlanIdAction().getVlanId())
+                                .setEthernetType(sourceFlow.getMatch().getEthernetMatch()
+                                        .getEthernetType().getType().getValue().intValue())
+                                .setTag(sourceFlow.getMatch().getEthernetMatch()
+                                        .getEthernetType().getType().getValue().intValue());
+                        pushVlanActionCaseBuilder.setPushVlanAction(pushVlanActionBuilder.build());
+                        PushVlanActionCase injectedAction = pushVlanActionCaseBuilder.build();
 
-                if (ipv6Match.getIpv6NdTll() != null) {
-                    matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                    matchEntriesBuilder.setHasMask(false);
-                    matchEntriesBuilder.setOxmMatchField(Ipv6NdTll.class);
-                    addMacAddressAugmentation(matchEntriesBuilder, ipv6Match.getIpv6NdTll());
-                    matchEntriesList.add(matchEntriesBuilder.build());
-                }
+                        org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder actionBuilder = new ActionBuilder();
+                        actionBuilder.setAction(injectedAction)
+                                .setKey(actionItem.getKey())
+                                .setOrder(actionItem.getOrder() + offset);
 
-                if (ipv6Match.getIpv6Exthdr() != null) {
-                    matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                    matchEntriesBuilder.setHasMask(false);
-                    matchEntriesBuilder.setOxmMatchField(Ipv6Exthdr.class);
-                    PseudoFieldMatchEntryBuilder pseudoBuilder = new PseudoFieldMatchEntryBuilder();
-                    Integer bitmap = ipv6Match.getIpv6Exthdr();
-                    final Boolean NONEXT = ((bitmap) & (1 << 0)) != 0;
-                    final Boolean ESP = ((bitmap) & (1 << 1)) != 0;
-                    final Boolean AUTH = ((bitmap) & (1 << 2)) != 0;
-                    final Boolean DEST = ((bitmap) & (1 << 3)) != 0;
-                    final Boolean FRAG = ((bitmap) & (1 << 4)) != 0;
-                    final Boolean ROUTER = ((bitmap) & (1 << 5)) != 0;
-                    final Boolean HOP = ((bitmap) & (1 << 6)) != 0;
-                    final Boolean UNREP = ((bitmap) & (1 << 7)) != 0;
-                    final Boolean UNSEQ = ((bitmap) & (1 << 8)) != 0;
-                    pseudoBuilder.setPseudoField(new PseudoField(AUTH, DEST, ESP, FRAG, HOP, NONEXT, ROUTER, UNREP,
-                            UNSEQ));
-                    matchEntriesBuilder.addAugmentation(PseudoFieldMatchEntry.class, pseudoBuilder.build());
-                    addMaskAugmentation(matchEntriesBuilder, ByteBuffer.allocate(2).putInt(bitmap).array());
-                    matchEntriesList.add(matchEntriesBuilder.build());
-                }
-            }
-        }
+                        targetActionList.add(actionBuilder.build());
+                        offset++;
+                    }
 
-        ProtocolMatchFields protocolMatchFields = match.getProtocolMatchFields();
-        if (protocolMatchFields != null) {
-            if (protocolMatchFields.getMplsLabel() != null) {
-                matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                matchEntriesBuilder.setHasMask(false);
-                matchEntriesBuilder.setOxmMatchField(MplsLabel.class);
-                MplsLabelMatchEntryBuilder mplsLabelBuilder = new MplsLabelMatchEntryBuilder();
-                mplsLabelBuilder.setMplsLabel(protocolMatchFields.getMplsLabel());
-                matchEntriesBuilder.addAugmentation(MplsLabelMatchEntry.class, mplsLabelBuilder.build());
-                matchEntriesList.add(matchEntriesBuilder.build());
-            }
+                    if (offset > 0) {
+                        // we need to increment the order for all the actions added after injection
+                        org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder actionBuilder =
+                                new org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder(actionItem);
+                        actionBuilder.setOrder(actionItem.getOrder() + offset);
+                        actionItem = actionBuilder.build();
+                    }
 
-            if (protocolMatchFields.getMplsBos() != null) {
-                matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                matchEntriesBuilder.setHasMask(false);
-                matchEntriesBuilder.setOxmMatchField(MplsBos.class);
-                BosMatchEntryBuilder bosBuilder = new BosMatchEntryBuilder();
-                if (protocolMatchFields.getMplsBos() != 0) {
-                    bosBuilder.setBos(true);
-                } else {
-                    bosBuilder.setBos(false);
+                    targetActionList.add(actionItem);
                 }
-                matchEntriesBuilder.addAugmentation(BosMatchEntry.class, bosBuilder.build());
-                matchEntriesList.add(matchEntriesBuilder.build());
-            }
 
-            if (protocolMatchFields.getMplsTc() != null) {
-                matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                matchEntriesBuilder.setHasMask(false);
-                matchEntriesBuilder.setOxmMatchField(MplsTc.class);
-                TcMatchEntryBuilder tcBuilder = new TcMatchEntryBuilder();
-                tcBuilder.setTc(protocolMatchFields.getMplsTc());
-                matchEntriesBuilder.addAugmentation(TcMatchEntry.class, tcBuilder.build());
-                matchEntriesList.add(matchEntriesBuilder.build());
-            }
+                ApplyActionsCaseBuilder applyActionsCaseBuilder = new ApplyActionsCaseBuilder();
+                ApplyActionsBuilder applyActionsBuilder = new ApplyActionsBuilder();
+                applyActionsBuilder.setAction(targetActionList);
+                applyActionsCaseBuilder.setApplyActions(applyActionsBuilder.build());
 
-            if (protocolMatchFields.getPbb() != null) {
-                matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-                // verify
-                matchEntriesBuilder.setHasMask(false);
-                matchEntriesBuilder.setOxmMatchField(PbbIsid.class);
-                IsidMatchEntryBuilder isidBuilder = new IsidMatchEntryBuilder();
-                isidBuilder.setIsid(protocolMatchFields.getPbb().getPbbIsid());
-                matchEntriesBuilder.addAugmentation(IsidMatchEntry.class, isidBuilder.build());
-                if (protocolMatchFields.getPbb().getPbbMask() != null) {
-                    addMaskAugmentation(matchEntriesBuilder, protocolMatchFields.getPbb().getPbbMask());
-                }
-                matchEntriesList.add(matchEntriesBuilder.build());
-            }
-        }
-
-        if (match.getTunnel() != null) {
-            matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
-            matchEntriesBuilder.setHasMask(false);
-            matchEntriesBuilder.setOxmMatchField(TunnelId.class);
-            addMetadataAugmentation(matchEntriesBuilder, match.getTunnel().getTunnelId());
-            if (match.getTunnel().getTunnelMask() != null) {
-                addMaskAugmentation(matchEntriesBuilder, match.getTunnel().getTunnelMask());
-            }
-        }
-
-        matchBuilder.setMatchEntries(matchEntriesList);
-        return matchBuilder.build();
-    }
-
-    private static List<Instructions> toInstructions(
-            org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions instructions) {
-        List<Instructions> instructionsList = new ArrayList<>();
-        InstructionsBuilder instructionBuilder = new InstructionsBuilder();
-
-        for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction instruction : instructions
-                .getInstruction()) {
-            org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction curInstruction = instruction
-                    .getInstruction();
-            if (curInstruction instanceof GoToTable) {
-                GoToTable goToTable = (GoToTable) curInstruction;
-                instructionBuilder
-                        .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.GotoTable.class);
-                TableIdInstructionBuilder tableBuilder = new TableIdInstructionBuilder();
-                tableBuilder.setTableId(goToTable.getTableId());
-                instructionBuilder.addAugmentation(TableIdInstruction.class, tableBuilder.build());
-            }
-
-            else if (curInstruction instanceof WriteMetadata) {
-                WriteMetadata writeMetadata = (WriteMetadata) curInstruction;
-                instructionBuilder
-                        .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteMetadata.class);
-                MetadataInstructionBuilder metadataBuilder = new MetadataInstructionBuilder();
-                metadataBuilder.setMetadata(writeMetadata.getMetadata().toByteArray());
-                metadataBuilder.setMetadataMask(writeMetadata.getMetadataMask().toByteArray());
-                instructionBuilder.addAugmentation(MetadataInstruction.class, metadataBuilder.build());
-            }
-
-            else if (curInstruction instanceof WriteActions) {
-                WriteActions writeActions = (WriteActions) curInstruction;
-                instructionBuilder
-                        .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteActions.class);
-                ActionsInstructionBuilder actionsInstructionBuilder = new ActionsInstructionBuilder();
-                actionsInstructionBuilder.setActionsList(ActionConvertor.getActionList(writeActions.getAction()));
-                instructionBuilder.addAugmentation(ActionsInstruction.class, actionsInstructionBuilder.build());
-            }
-
-            else if (curInstruction instanceof ApplyActions) {
-                ApplyActions applyActions = (ApplyActions) curInstruction;
-                instructionBuilder
-                        .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ApplyActions.class);
-                ActionsInstructionBuilder actionsInstructionBuilder = new ActionsInstructionBuilder();
-                actionsInstructionBuilder.setActionsList(ActionConvertor.getActionList(applyActions.getAction()));
-                instructionBuilder.addAugmentation(ActionsInstruction.class, actionsInstructionBuilder.build());
-            }
-
-            else if (curInstruction instanceof ClearActions) {
-                ClearActions clearActions = (ClearActions) curInstruction;
-                instructionBuilder
-                        .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ClearActions.class);
-                ActionsInstructionBuilder actionsInstructionBuilder = new ActionsInstructionBuilder();
-                actionsInstructionBuilder.setActionsList(ActionConvertor.getActionList(clearActions.getAction()));
-                instructionBuilder.addAugmentation(ActionsInstruction.class, actionsInstructionBuilder.build());
-            }
-
-            else if (curInstruction instanceof Meter) {
-                Meter meter = (Meter) curInstruction;
-                instructionBuilder
-                        .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.Meter.class);
-                MeterIdInstructionBuilder meterBuilder = new MeterIdInstructionBuilder();
-                Long meterId = Long.parseLong(meter.getMeter());
-                meterBuilder.setMeterId(meterId);
-                instructionBuilder.addAugmentation(MeterIdInstruction.class, meterBuilder.build());
+                instructionBuilder.setInstruction(applyActionsCaseBuilder.build());
+            } else {
+                instructionBuilder.setInstruction(curSrcInstruction);
             }
 
-            instructionsList.add(instructionBuilder.build());
-        }
-        return instructionsList;
-    }
-
-    private static void addMaskAugmentation(MatchEntriesBuilder builder, byte[] mask) {
-        MaskMatchEntryBuilder maskBuilder = new MaskMatchEntryBuilder();
-        maskBuilder.setMask(mask);
-        builder.addAugmentation(MaskMatchEntry.class, maskBuilder.build());
-        builder.setHasMask(true);
-    }
-
-    private static void addIpv6AddressAugmentation(MatchEntriesBuilder builder, Ipv6Address address) {
-        Ipv6AddressMatchEntryBuilder ipv6AddressBuilder = new Ipv6AddressMatchEntryBuilder();
-        ipv6AddressBuilder.setIpv6Address(address);
-        builder.addAugmentation(Ipv6AddressMatchEntry.class, ipv6AddressBuilder.build());
-    }
-
-    private static void addIpv6PrefixAugmentation(MatchEntriesBuilder builder, Ipv6Prefix address) {
-        String[] addressParts = address.getValue().split(PREFIX_SEPARATOR);
-        Integer prefix = null;
-        if (addressParts.length == 2) {
-            prefix = Integer.parseInt(addressParts[1]);
-        }
-
-        Ipv6Address ipv6Address = new Ipv6Address(addressParts[0]);
-        Ipv6AddressMatchEntryBuilder ipv6AddressBuilder = new Ipv6AddressMatchEntryBuilder();
-        ipv6AddressBuilder.setIpv6Address(ipv6Address);
-        builder.addAugmentation(Ipv6AddressMatchEntry.class, ipv6AddressBuilder.build());
-        if (prefix != null) {
-            addMaskAugmentation(builder, ByteBuffer.allocate(2).putInt(prefix).array());
-        }
-    }
-
-    private static void addMetadataAugmentation(MatchEntriesBuilder builder, BigInteger metadata) {
-        MetadataMatchEntryBuilder metadataMatchEntry = new MetadataMatchEntryBuilder();
-        metadataMatchEntry.setMetadata(metadata.toByteArray());
-        builder.addAugmentation(MetadataMatchEntry.class, metadataMatchEntry.build());
-    }
+            instructionBuilder
+                    .setKey(srcInstruction.getKey())
+                    .setOrder(srcInstruction.getOrder());
+            targetInstructionList.add(instructionBuilder.build());
 
-    private static void addIpv4PrefixAugmentation(MatchEntriesBuilder builder, Ipv4Prefix address) {
-        String[] addressParts = address.getValue().split(PREFIX_SEPARATOR);
-        Integer prefix = null;
-        if (addressParts.length == 2) {
-            prefix = Integer.parseInt(addressParts[1]);
         }
 
-        Ipv4Address ipv4Address = new Ipv4Address(addressParts[0]);
-        Ipv4AddressMatchEntryBuilder ipv4AddressBuilder = new Ipv4AddressMatchEntryBuilder();
-        ipv4AddressBuilder.setIpv4Address(ipv4Address);
-        builder.addAugmentation(Ipv4AddressMatchEntry.class, ipv4AddressBuilder.build());
-        if (prefix != null) {
-            addMaskAugmentation(builder, ByteBuffer.allocate(1).putInt(prefix).array());
-        }
+        return targetInstructionList;
     }
 
-    private static void addMacAddressAugmentation(MatchEntriesBuilder builder, MacAddress address) {
-        MacAddressMatchEntryBuilder macAddress = new MacAddressMatchEntryBuilder();
-        macAddress.setMacAddress(address);
-        builder.addAugmentation(MacAddressMatchEntry.class, macAddress.build());
-    }
-
-    private static void addPortAugmentation(MatchEntriesBuilder builder,
-            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber port) {
-        PortMatchEntryBuilder portBuilder = new PortMatchEntryBuilder();
-        portBuilder.setPort(port);
-        builder.addAugmentation(PortMatchEntry.class, portBuilder.build());
-    }
-}
\ No newline at end of file
+}