private OFAction buildL2Modification(Instruction i) {
    L2ModificationInstruction l2m = (L2ModificationInstruction) i;
    ModEtherInstruction eth;
    OFOxm<?> oxm = null;
    switch (l2m.subtype()) {
      case ETH_DST:
        eth = (ModEtherInstruction) l2m;
        oxm = factory().oxms().ethDst(MacAddress.of(eth.mac().toLong()));
        break;
      case ETH_SRC:
        eth = (ModEtherInstruction) l2m;
        oxm = factory().oxms().ethSrc(MacAddress.of(eth.mac().toLong()));
        break;
      case VLAN_ID:
        ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
        oxm = factory().oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanId.vlanId().toShort()));
        break;
      case VLAN_PCP:
        ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
        oxm = factory().oxms().vlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
        break;
      case MPLS_PUSH:
        PushHeaderInstructions pushHeaderInstructions = (PushHeaderInstructions) l2m;
        return factory()
            .actions()
            .pushMpls(EthType.of(pushHeaderInstructions.ethernetType().toShort()));
      case MPLS_POP:
        PushHeaderInstructions popHeaderInstructions = (PushHeaderInstructions) l2m;
        return factory()
            .actions()
            .popMpls(EthType.of(popHeaderInstructions.ethernetType().toShort()));
      case MPLS_LABEL:
        ModMplsLabelInstruction mplsLabel = (ModMplsLabelInstruction) l2m;
        oxm = factory().oxms().mplsLabel(U32.of(mplsLabel.label().longValue()));
        break;
      case DEC_MPLS_TTL:
        return factory().actions().decMplsTtl();
      case VLAN_POP:
        return factory().actions().popVlan();
      case VLAN_PUSH:
        PushHeaderInstructions pushVlanInstruction = (PushHeaderInstructions) l2m;
        return factory()
            .actions()
            .pushVlan(EthType.of(pushVlanInstruction.ethernetType().toShort()));
      default:
        log.warn("Unimplemented action type {}.", l2m.subtype());
        break;
    }

    if (oxm != null) {
      return factory().actions().buildSetField().setField(oxm).build();
    }
    return null;
  }
  /**
   * Matches the contents of a mod vlan id instruction.
   *
   * @param instructionJson JSON instruction to match
   * @param description Description object used for recording errors
   * @return true if contents match, false otherwise
   */
  private boolean matchModVlanIdInstruction(JsonNode instructionJson, Description description) {
    ModVlanIdInstruction instructionToMatch = (ModVlanIdInstruction) instruction;
    final String jsonSubtype = instructionJson.get("subtype").textValue();
    if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
      description.appendText("subtype was " + jsonSubtype);
      return false;
    }

    final String jsonType = instructionJson.get("type").textValue();
    if (!instructionToMatch.type().name().equals(jsonType)) {
      description.appendText("type was " + jsonType);
      return false;
    }

    final short jsonVlanId = instructionJson.get("vlanId").shortValue();
    final short vlanId = instructionToMatch.vlanId().toShort();
    if (jsonVlanId != vlanId) {
      description.appendText("vlan id was " + jsonVlanId);
      return false;
    }

    return true;
  }