Mass replace CRLF->LF
[openflowjava.git] / openflow-protocol-impl / src / test / java / org / opendaylight / openflowjava / protocol / impl / serialization / factories / multipart / MultipartRequestTableFeaturesTest.java
index 86f0fef411a609c619f2e7e768309de2f6c670a3..6ece76796290c1ff8a71fbf057d5ee4bf4081ed8 100644 (file)
-/*\r
- * Copyright (c) 2013 Pantheon Technologies s.r.o. and others.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-package org.opendaylight.openflowjava.protocol.impl.serialization.factories.multipart;\r
-\r
-import io.netty.buffer.ByteBuf;\r
-import io.netty.buffer.UnpooledByteBufAllocator;\r
-\r
-import java.math.BigInteger;\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-import org.junit.Assert;\r
-import org.junit.Before;\r
-import org.junit.Test;\r
-import org.junit.runner.RunWith;\r
-import org.mockito.Matchers;\r
-import org.mockito.Mock;\r
-import org.mockito.Mockito;\r
-import org.mockito.runners.MockitoJUnitRunner;\r
-import org.opendaylight.openflowjava.protocol.api.extensibility.MessageTypeKey;\r
-import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer;\r
-import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry;\r
-import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;\r
-import org.opendaylight.openflowjava.protocol.impl.serialization.SerializerRegistryImpl;\r
-import org.opendaylight.openflowjava.protocol.impl.serialization.factories.MultipartRequestInputFactory;\r
-import org.opendaylight.openflowjava.protocol.impl.serialization.factories.MultipartRequestInputFactoryTest;\r
-import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper;\r
-import org.opendaylight.openflowjava.util.ByteBufUtils;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionRelatedTableFeatureProperty;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionRelatedTableFeaturePropertyBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterIdTableFeatureProperty;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterIdTableFeaturePropertyBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.InstructionRelatedTableFeatureProperty;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.InstructionRelatedTableFeaturePropertyBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NextTableRelatedTableFeatureProperty;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NextTableRelatedTableFeaturePropertyBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmRelatedTableFeatureProperty;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmRelatedTableFeaturePropertyBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.table.features.properties.container.table.feature.properties.NextTableIds;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.table.features.properties.container.table.feature.properties.NextTableIdsBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Output;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.grouping.Action;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.grouping.ActionBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ApplyActions;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ClearActions;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.GotoTable;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.Meter;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteActions;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteMetadata;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.InstructionBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ExperimenterId;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableConfig;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableFeaturesPropType;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.InPhyPort;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.InPort;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.IpEcn;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.IpProto;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OpenflowBasicClass;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntries;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntriesBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInputBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCaseBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.MultipartRequestTableFeaturesBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeatures;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeaturesBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeaturePropertiesBuilder;\r
-\r
-/**\r
- * @author michal.polkorab\r
- *\r
- */\r
-@RunWith(MockitoJUnitRunner.class)\r
-public class MultipartRequestTableFeaturesTest {\r
-\r
-    private static final byte PADDING_IN_MULTIPART_REQUEST_MESSAGE =\r
-            MultipartRequestInputFactoryTest.PADDING_IN_MULTIPART_REQUEST_MESSAGE;\r
-    private SerializerRegistry registry;\r
-    private OFSerializer<MultipartRequestInput> multipartFactory;\r
-\r
-    @Mock SerializerRegistry mockRegistry;\r
-    @Mock OFSerializer<TableFeatureProperties> serializer;\r
-\r
-    /**\r
-     * Initializes serializer registry and stores correct factory in field\r
-     */\r
-    @Before\r
-    public void startUp() {\r
-        Mockito.when(mockRegistry.getSerializer((MessageTypeKey<?>)Matchers.any()))\r
-        .thenReturn(serializer);\r
-        registry = new SerializerRegistryImpl();\r
-        registry.init();\r
-        multipartFactory = registry.getSerializer(\r
-                new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, MultipartRequestInput.class));\r
-    }\r
-\r
-    /**\r
-     * @throws Exception\r
-     * Testing of {@link MultipartRequestInputFactory} for correct translation from POJO\r
-     */\r
-    @Test\r
-    public void testMultipartRequestTableFeaturesMessageFactory() throws Exception {\r
-        MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder();\r
-        BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID);\r
-        builder.setType(MultipartType.forValue(12));\r
-        builder.setFlags(new MultipartRequestFlags(true));\r
-        MultipartRequestTableFeaturesCaseBuilder caseBuilder = new MultipartRequestTableFeaturesCaseBuilder();\r
-        MultipartRequestTableFeaturesBuilder featuresBuilder = new MultipartRequestTableFeaturesBuilder();\r
-        List<TableFeatures> tableFeaturesList = new ArrayList<>();\r
-        TableFeaturesBuilder tableFeaturesBuilder = new TableFeaturesBuilder();\r
-        tableFeaturesBuilder.setTableId((short) 8);\r
-        tableFeaturesBuilder.setName("AAAABBBBCCCCDDDDEEEEFFFFGGGG");\r
-        tableFeaturesBuilder.setMetadataMatch(new BigInteger(new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}));\r
-        tableFeaturesBuilder.setMetadataWrite(new BigInteger(new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}));\r
-        tableFeaturesBuilder.setConfig(new TableConfig(true));\r
-        tableFeaturesBuilder.setMaxEntries(65L);\r
-        List<TableFeatureProperties> properties = new ArrayList<>();\r
-        TableFeaturePropertiesBuilder propBuilder = new TableFeaturePropertiesBuilder();\r
-        propBuilder.setType(TableFeaturesPropType.OFPTFPTNEXTTABLES);\r
-        NextTableRelatedTableFeaturePropertyBuilder nextPropBuilder =\r
-                new NextTableRelatedTableFeaturePropertyBuilder();\r
-        List<NextTableIds> nextIds = new ArrayList<>();\r
-        nextIds.add(new NextTableIdsBuilder().setTableId((short) 1).build());\r
-        nextIds.add(new NextTableIdsBuilder().setTableId((short) 2).build());\r
-        nextPropBuilder.setNextTableIds(nextIds);\r
-        propBuilder.addAugmentation(NextTableRelatedTableFeatureProperty.class, nextPropBuilder.build());\r
-        properties.add(propBuilder.build());\r
-        propBuilder = new TableFeaturePropertiesBuilder();\r
-        propBuilder.setType(TableFeaturesPropType.OFPTFPTNEXTTABLESMISS);\r
-        nextPropBuilder = new NextTableRelatedTableFeaturePropertyBuilder();\r
-        nextIds = new ArrayList<>();\r
-        nextPropBuilder.setNextTableIds(nextIds);\r
-        propBuilder.addAugmentation(NextTableRelatedTableFeatureProperty.class, nextPropBuilder.build());\r
-        properties.add(propBuilder.build());\r
-        propBuilder = new TableFeaturePropertiesBuilder();\r
-        propBuilder.setType(TableFeaturesPropType.OFPTFPTINSTRUCTIONS);\r
-        InstructionRelatedTableFeaturePropertyBuilder insPropBuilder =\r
-                new InstructionRelatedTableFeaturePropertyBuilder();\r
-        List<Instruction> insIds = new ArrayList<>();\r
-        InstructionBuilder insBuilder = new InstructionBuilder();\r
-        insBuilder.setType(WriteActions.class);\r
-        insIds.add(insBuilder.build());\r
-        insBuilder = new InstructionBuilder();\r
-        insBuilder.setType(GotoTable.class);\r
-        insIds.add(insBuilder.build());\r
-        insPropBuilder.setInstruction(insIds);\r
-        propBuilder.addAugmentation(InstructionRelatedTableFeatureProperty.class, insPropBuilder.build());\r
-        properties.add(propBuilder.build());\r
-        propBuilder = new TableFeaturePropertiesBuilder();\r
-        propBuilder.setType(TableFeaturesPropType.OFPTFPTINSTRUCTIONSMISS);\r
-        insPropBuilder = new InstructionRelatedTableFeaturePropertyBuilder();\r
-        insIds = new ArrayList<>();\r
-        insBuilder = new InstructionBuilder();\r
-        insBuilder.setType(WriteMetadata.class);\r
-        insIds.add(insBuilder.build());\r
-        insBuilder = new InstructionBuilder();\r
-        insBuilder.setType(ApplyActions.class);\r
-        insIds.add(insBuilder.build());\r
-        insBuilder = new InstructionBuilder();\r
-        insBuilder.setType(Meter.class);\r
-        insIds.add(insBuilder.build());\r
-        insBuilder = new InstructionBuilder();\r
-        insBuilder.setType(ClearActions.class);\r
-        insIds.add(insBuilder.build());\r
-        insBuilder = new InstructionBuilder();\r
-        insBuilder.setType(GotoTable.class);\r
-        insIds.add(insBuilder.build());\r
-        insPropBuilder.setInstruction(insIds);\r
-        propBuilder.addAugmentation(InstructionRelatedTableFeatureProperty.class, insPropBuilder.build());\r
-        properties.add(propBuilder.build());\r
-        tableFeaturesBuilder.setTableFeatureProperties(properties);\r
-        tableFeaturesList.add(tableFeaturesBuilder.build());\r
-        tableFeaturesBuilder = new TableFeaturesBuilder();\r
-        tableFeaturesBuilder.setTableId((short) 8);\r
-        tableFeaturesBuilder.setName("AAAABBBBCCCCDDDDEEEEFFFFGGGG");\r
-        tableFeaturesBuilder.setMetadataMatch(new BigInteger(new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}));\r
-        tableFeaturesBuilder.setMetadataWrite(new BigInteger(new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}));\r
-        tableFeaturesBuilder.setConfig(new TableConfig(true));\r
-        tableFeaturesBuilder.setMaxEntries(67L);\r
-        properties = new ArrayList<>();\r
-        propBuilder = new TableFeaturePropertiesBuilder();\r
-        propBuilder.setType(TableFeaturesPropType.OFPTFPTWRITEACTIONS);\r
-        ActionRelatedTableFeaturePropertyBuilder actBuilder = new ActionRelatedTableFeaturePropertyBuilder();\r
-        List<Action> actions = new ArrayList<>();\r
-        ActionBuilder actionBuilder = new ActionBuilder();\r
-        actionBuilder.setType(Output.class);\r
-        actions.add(actionBuilder.build());\r
-        actBuilder.setAction(actions);\r
-        propBuilder.addAugmentation(ActionRelatedTableFeatureProperty.class, actBuilder.build());\r
-        properties.add(propBuilder.build());\r
-        propBuilder = new TableFeaturePropertiesBuilder();\r
-        propBuilder.setType(TableFeaturesPropType.OFPTFPTWRITEACTIONSMISS);\r
-        actBuilder = new ActionRelatedTableFeaturePropertyBuilder();\r
-        actions = new ArrayList<>();\r
-        actBuilder.setAction(actions);\r
-        propBuilder.addAugmentation(ActionRelatedTableFeatureProperty.class, actBuilder.build());\r
-        properties.add(propBuilder.build());\r
-        propBuilder = new TableFeaturePropertiesBuilder();\r
-        propBuilder.setType(TableFeaturesPropType.OFPTFPTAPPLYACTIONS);\r
-        actBuilder = new ActionRelatedTableFeaturePropertyBuilder();\r
-        actions = new ArrayList<>();\r
-        actBuilder.setAction(actions);\r
-        propBuilder.addAugmentation(ActionRelatedTableFeatureProperty.class, actBuilder.build());\r
-        properties.add(propBuilder.build());\r
-        propBuilder = new TableFeaturePropertiesBuilder();\r
-        propBuilder.setType(TableFeaturesPropType.OFPTFPTAPPLYACTIONSMISS);\r
-        actBuilder = new ActionRelatedTableFeaturePropertyBuilder();\r
-        actions = new ArrayList<>();\r
-        actBuilder.setAction(actions);\r
-        propBuilder.addAugmentation(ActionRelatedTableFeatureProperty.class, actBuilder.build());\r
-        properties.add(propBuilder.build());\r
-        propBuilder = new TableFeaturePropertiesBuilder();\r
-        propBuilder.setType(TableFeaturesPropType.OFPTFPTMATCH);\r
-        OxmRelatedTableFeaturePropertyBuilder oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder();\r
-        List<MatchEntries> entries = new ArrayList<>();\r
-        MatchEntriesBuilder entriesBuilder = new MatchEntriesBuilder();\r
-        entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
-        entriesBuilder.setOxmMatchField(InPhyPort.class);\r
-        entriesBuilder.setHasMask(false);\r
-        entries.add(entriesBuilder.build());\r
-        entriesBuilder = new MatchEntriesBuilder();\r
-        entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
-        entriesBuilder.setOxmMatchField(InPort.class);\r
-        entriesBuilder.setHasMask(false);\r
-        entries.add(entriesBuilder.build());\r
-        oxmBuilder.setMatchEntries(entries);\r
-        propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build());\r
-        properties.add(propBuilder.build());\r
-        propBuilder = new TableFeaturePropertiesBuilder();\r
-        propBuilder.setType(TableFeaturesPropType.OFPTFPTWILDCARDS);\r
-        oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder();\r
-        entries = new ArrayList<>();\r
-        oxmBuilder.setMatchEntries(entries);\r
-        propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build());\r
-        properties.add(propBuilder.build());\r
-        propBuilder = new TableFeaturePropertiesBuilder();\r
-        propBuilder.setType(TableFeaturesPropType.OFPTFPTWRITESETFIELD);\r
-        oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder();\r
-        entries = new ArrayList<>();\r
-        oxmBuilder.setMatchEntries(entries);\r
-        propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build());\r
-        properties.add(propBuilder.build());\r
-        propBuilder = new TableFeaturePropertiesBuilder();\r
-        propBuilder.setType(TableFeaturesPropType.OFPTFPTWRITESETFIELDMISS);\r
-        oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder();\r
-        entries = new ArrayList<>();\r
-        oxmBuilder.setMatchEntries(entries);\r
-        propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build());\r
-        properties.add(propBuilder.build());\r
-        propBuilder = new TableFeaturePropertiesBuilder();\r
-        propBuilder.setType(TableFeaturesPropType.OFPTFPTAPPLYSETFIELD);\r
-        oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder();\r
-        entries = new ArrayList<>();\r
-        entriesBuilder = new MatchEntriesBuilder();\r
-        entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
-        entriesBuilder.setOxmMatchField(IpProto.class);\r
-        entriesBuilder.setHasMask(false);\r
-        entries.add(entriesBuilder.build());\r
-        entriesBuilder = new MatchEntriesBuilder();\r
-        entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
-        entriesBuilder.setOxmMatchField(IpEcn.class);\r
-        entriesBuilder.setHasMask(false);\r
-        entries.add(entriesBuilder.build());\r
-        oxmBuilder.setMatchEntries(entries);\r
-        propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build());\r
-        properties.add(propBuilder.build());\r
-        propBuilder = new TableFeaturePropertiesBuilder();\r
-        propBuilder.setType(TableFeaturesPropType.OFPTFPTAPPLYSETFIELDMISS);\r
-        oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder();\r
-        entries = new ArrayList<>();\r
-        oxmBuilder.setMatchEntries(entries);\r
-        propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build());\r
-        properties.add(propBuilder.build());\r
-        tableFeaturesBuilder.setTableFeatureProperties(properties);\r
-        tableFeaturesList.add(tableFeaturesBuilder.build());\r
-        featuresBuilder.setTableFeatures(tableFeaturesList);\r
-        caseBuilder.setMultipartRequestTableFeatures(featuresBuilder.build());\r
-        builder.setMultipartRequestBody(caseBuilder.build());\r
-        MultipartRequestInput message = builder.build();\r
-\r
-        ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer();\r
-        multipartFactory.serialize(message, out);\r
-\r
-        BufferHelper.checkHeaderV13(out, (byte) 18, 296);\r
-        Assert.assertEquals("Wrong type", 12, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong flags", 1, out.readUnsignedShort());\r
-        out.skipBytes(PADDING_IN_MULTIPART_REQUEST_MESSAGE);\r
-        Assert.assertEquals("Wrong length", 120, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong registry-id", 8, out.readUnsignedByte());\r
-        out.skipBytes(5);\r
-        Assert.assertEquals("Wrong name", "AAAABBBBCCCCDDDDEEEEFFFFGGGG",\r
-                ByteBufUtils.decodeNullTerminatedString(out, 32));\r
-        byte[] metadataMatch = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];\r
-        out.readBytes(metadataMatch);\r
-        Assert.assertArrayEquals("Wrong metadata-match",\r
-                new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}, metadataMatch);\r
-        byte[] metadataWrite = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];\r
-        out.readBytes(metadataWrite);\r
-        Assert.assertArrayEquals("Wrong metadata-write",\r
-                new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}, metadataWrite);\r
-        Assert.assertEquals("Wrong config", 8, out.readUnsignedInt());\r
-        Assert.assertEquals("Wrong max-entries", 65, out.readUnsignedInt());\r
-        Assert.assertEquals("Wrong property type", 2, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong property length", 6, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong next-registry-id", 1, out.readUnsignedByte());\r
-        Assert.assertEquals("Wrong next-registry-id", 2, out.readUnsignedByte());\r
-        out.skipBytes(2);\r
-        Assert.assertEquals("Wrong property type", 3, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort());\r
-        out.skipBytes(4);\r
-        Assert.assertEquals("Wrong property type", 0, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong property length", 12, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong instruction type", 3, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong instruction type", 1, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());\r
-        out.skipBytes(4);\r
-        Assert.assertEquals("Wrong property type", 1, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong property length", 24, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong instruction type", 2, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong instruction type", 4, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong instruction type", 6, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong instruction type", 5, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong instruction type", 1, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong length", 160, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong registry-id", 8, out.readUnsignedByte());\r
-        out.skipBytes(5);\r
-        Assert.assertEquals("Wrong name", "AAAABBBBCCCCDDDDEEEEFFFFGGGG",\r
-                ByteBufUtils.decodeNullTerminatedString(out, 32));\r
-        metadataMatch = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];\r
-        out.readBytes(metadataMatch);\r
-        Assert.assertArrayEquals("Wrong metadata-match",\r
-                new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}, metadataMatch);\r
-        metadataWrite = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];\r
-        out.readBytes(metadataWrite);\r
-        Assert.assertArrayEquals("Wrong metadata-write",\r
-                new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}, metadataWrite);\r
-        Assert.assertEquals("Wrong config", 8, out.readUnsignedInt());\r
-        Assert.assertEquals("Wrong max-entries", 67, out.readUnsignedInt());\r
-        Assert.assertEquals("Wrong property type", 4, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong property length", 8, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong action type", 0, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong action length", 4, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong property type", 5, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort());\r
-        out.skipBytes(4);\r
-        Assert.assertEquals("Wrong property type", 6, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort());\r
-        out.skipBytes(4);\r
-        Assert.assertEquals("Wrong property type", 7, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort());\r
-        out.skipBytes(4);\r
-        Assert.assertEquals("Wrong property type", 8, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong property length", 12, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong match class", 0x8000, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong match field&mask", 2, out.readUnsignedByte());\r
-        Assert.assertEquals("Wrong match length", 4, out.readUnsignedByte());\r
-        Assert.assertEquals("Wrong match class", 0x8000, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong match field&mask", 0, out.readUnsignedByte());\r
-        Assert.assertEquals("Wrong match length", 4, out.readUnsignedByte());\r
-        out.skipBytes(4);\r
-        Assert.assertEquals("Wrong property type", 10, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort());\r
-        out.skipBytes(4);\r
-        Assert.assertEquals("Wrong property type", 12, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort());\r
-        out.skipBytes(4);\r
-        Assert.assertEquals("Wrong property type", 13, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort());\r
-        out.skipBytes(4);\r
-        Assert.assertEquals("Wrong property type", 14, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong property length", 12, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong match class", 0x8000, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong match field&mask", 20, out.readUnsignedByte());\r
-        Assert.assertEquals("Wrong match length", 1, out.readUnsignedByte());\r
-        Assert.assertEquals("Wrong match class", 0x8000, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong match field&mask", 18, out.readUnsignedByte());\r
-        Assert.assertEquals("Wrong match length", 1, out.readUnsignedByte());\r
-        out.skipBytes(4);\r
-        Assert.assertEquals("Wrong property type", 15, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort());\r
-        out.skipBytes(4);\r
-        Assert.assertTrue("Unread data", out.readableBytes() == 0);\r
-    }\r
-\r
-    /**\r
-     * @throws Exception\r
-     * Testing of {@link MultipartRequestInputFactory} for correct translation from POJO\r
-     */\r
-    @Test\r
-    public void testMultipartRequestTableFeaturesExperimenter() throws Exception {\r
-        MultipartRequestInputFactory factory = new MultipartRequestInputFactory();\r
-        factory.injectSerializerRegistry(mockRegistry);\r
-        MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder();\r
-        BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID);\r
-        builder.setType(MultipartType.forValue(12));\r
-        builder.setFlags(new MultipartRequestFlags(true));\r
-        MultipartRequestTableFeaturesCaseBuilder caseBuilder = new MultipartRequestTableFeaturesCaseBuilder();\r
-        MultipartRequestTableFeaturesBuilder featuresBuilder = new MultipartRequestTableFeaturesBuilder();\r
-        List<TableFeatures> tableFeaturesList = new ArrayList<>();\r
-        TableFeaturesBuilder tableFeaturesBuilder = new TableFeaturesBuilder();\r
-        tableFeaturesBuilder.setTableId((short) 8);\r
-        tableFeaturesBuilder.setName("AAAABBBBCCCCDDDDEEEEFFFFGGGG");\r
-        tableFeaturesBuilder.setMetadataMatch(new BigInteger(new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}));\r
-        tableFeaturesBuilder.setMetadataWrite(new BigInteger(new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}));\r
-        tableFeaturesBuilder.setConfig(new TableConfig(true));\r
-        tableFeaturesBuilder.setMaxEntries(65L);\r
-        List<TableFeatureProperties> properties = new ArrayList<>();\r
-        TableFeaturePropertiesBuilder propBuilder = new TableFeaturePropertiesBuilder();\r
-        propBuilder.setType(TableFeaturesPropType.OFPTFPTEXPERIMENTER);\r
-        ExperimenterIdTableFeaturePropertyBuilder expBuilder = new ExperimenterIdTableFeaturePropertyBuilder();\r
-        expBuilder.setExperimenter(new ExperimenterId(42L));\r
-        propBuilder.addAugmentation(ExperimenterIdTableFeatureProperty.class, expBuilder.build());\r
-        properties.add(propBuilder.build());\r
-        propBuilder = new TableFeaturePropertiesBuilder();\r
-        propBuilder.setType(TableFeaturesPropType.OFPTFPTEXPERIMENTERMISS);\r
-        expBuilder = new ExperimenterIdTableFeaturePropertyBuilder();\r
-        expBuilder.setExperimenter(new ExperimenterId(43L));\r
-        propBuilder.addAugmentation(ExperimenterIdTableFeatureProperty.class, expBuilder.build());\r
-        properties.add(propBuilder.build());\r
-        tableFeaturesBuilder.setTableFeatureProperties(properties);\r
-        tableFeaturesList.add(tableFeaturesBuilder.build());\r
-        featuresBuilder.setTableFeatures(tableFeaturesList);\r
-        caseBuilder.setMultipartRequestTableFeatures(featuresBuilder.build());\r
-        builder.setMultipartRequestBody(caseBuilder.build());\r
-        MultipartRequestInput message = builder.build();\r
-\r
-        ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer();\r
-        factory.serialize(message, out);\r
-\r
-        BufferHelper.checkHeaderV13(out, (byte) 18, 80);\r
-        Assert.assertEquals("Wrong type", 12, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong flags", 1, out.readUnsignedShort());\r
-        out.skipBytes(PADDING_IN_MULTIPART_REQUEST_MESSAGE);\r
-        Assert.assertEquals("Wrong length", 64, out.readUnsignedShort());\r
-        Assert.assertEquals("Wrong registry-id", 8, out.readUnsignedByte());\r
-        out.skipBytes(5);\r
-        Assert.assertEquals("Wrong name", "AAAABBBBCCCCDDDDEEEEFFFFGGGG",\r
-                ByteBufUtils.decodeNullTerminatedString(out, 32));\r
-        byte[] metadataMatch = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];\r
-        out.readBytes(metadataMatch);\r
-        Assert.assertArrayEquals("Wrong metadata-match",\r
-                new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}, metadataMatch);\r
-        byte[] metadataWrite = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];\r
-        out.readBytes(metadataWrite);\r
-        Assert.assertArrayEquals("Wrong metadata-write",\r
-                new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}, metadataWrite);\r
-        Assert.assertEquals("Wrong config", 8, out.readUnsignedInt());\r
-        Assert.assertEquals("Wrong max-entries", 65, out.readUnsignedInt());\r
-        Mockito.verify(serializer, Mockito.times(2)).serialize(Matchers.any(TableFeatureProperties.class),\r
-                Matchers.any(ByteBuf.class));\r
-    }\r
+/*
+ * Copyright (c) 2013 Pantheon Technologies s.r.o. 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.openflowjava.protocol.impl.serialization.factories.multipart;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.UnpooledByteBufAllocator;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.openflowjava.protocol.api.extensibility.MessageTypeKey;
+import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer;
+import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry;
+import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
+import org.opendaylight.openflowjava.protocol.impl.serialization.SerializerRegistryImpl;
+import org.opendaylight.openflowjava.protocol.impl.serialization.factories.MultipartRequestInputFactory;
+import org.opendaylight.openflowjava.protocol.impl.serialization.factories.MultipartRequestInputFactoryTest;
+import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper;
+import org.opendaylight.openflowjava.util.ByteBufUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionRelatedTableFeatureProperty;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionRelatedTableFeaturePropertyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterIdTableFeatureProperty;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterIdTableFeaturePropertyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.InstructionRelatedTableFeatureProperty;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.InstructionRelatedTableFeaturePropertyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NextTableRelatedTableFeatureProperty;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NextTableRelatedTableFeaturePropertyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmRelatedTableFeatureProperty;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmRelatedTableFeaturePropertyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.table.features.properties.container.table.feature.properties.NextTableIds;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.table.features.properties.container.table.feature.properties.NextTableIdsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Output;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.grouping.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.grouping.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ApplyActions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ClearActions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.GotoTable;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteActions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteMetadata;
+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.ExperimenterId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableFeaturesPropType;
+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.IpEcn;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.IpProto;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OpenflowBasicClass;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntries;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntriesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.MultipartRequestTableFeaturesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeaturesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeaturePropertiesBuilder;
+
+/**
+ * @author michal.polkorab
+ *
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class MultipartRequestTableFeaturesTest {
+
+    private static final byte PADDING_IN_MULTIPART_REQUEST_MESSAGE =
+            MultipartRequestInputFactoryTest.PADDING_IN_MULTIPART_REQUEST_MESSAGE;
+    private SerializerRegistry registry;
+    private OFSerializer<MultipartRequestInput> multipartFactory;
+
+    @Mock SerializerRegistry mockRegistry;
+    @Mock OFSerializer<TableFeatureProperties> serializer;
+
+    /**
+     * Initializes serializer registry and stores correct factory in field
+     */
+    @Before
+    public void startUp() {
+        Mockito.when(mockRegistry.getSerializer((MessageTypeKey<?>)Matchers.any()))
+        .thenReturn(serializer);
+        registry = new SerializerRegistryImpl();
+        registry.init();
+        multipartFactory = registry.getSerializer(
+                new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, MultipartRequestInput.class));
+    }
+
+    /**
+     * @throws Exception
+     * Testing of {@link MultipartRequestInputFactory} for correct translation from POJO
+     */
+    @Test
+    public void testMultipartRequestTableFeaturesMessageFactory() throws Exception {
+        MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder();
+        BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID);
+        builder.setType(MultipartType.forValue(12));
+        builder.setFlags(new MultipartRequestFlags(true));
+        MultipartRequestTableFeaturesCaseBuilder caseBuilder = new MultipartRequestTableFeaturesCaseBuilder();
+        MultipartRequestTableFeaturesBuilder featuresBuilder = new MultipartRequestTableFeaturesBuilder();
+        List<TableFeatures> tableFeaturesList = new ArrayList<>();
+        TableFeaturesBuilder tableFeaturesBuilder = new TableFeaturesBuilder();
+        tableFeaturesBuilder.setTableId((short) 8);
+        tableFeaturesBuilder.setName("AAAABBBBCCCCDDDDEEEEFFFFGGGG");
+        tableFeaturesBuilder.setMetadataMatch(new BigInteger(new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}));
+        tableFeaturesBuilder.setMetadataWrite(new BigInteger(new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}));
+        tableFeaturesBuilder.setConfig(new TableConfig(true));
+        tableFeaturesBuilder.setMaxEntries(65L);
+        List<TableFeatureProperties> properties = new ArrayList<>();
+        TableFeaturePropertiesBuilder propBuilder = new TableFeaturePropertiesBuilder();
+        propBuilder.setType(TableFeaturesPropType.OFPTFPTNEXTTABLES);
+        NextTableRelatedTableFeaturePropertyBuilder nextPropBuilder =
+                new NextTableRelatedTableFeaturePropertyBuilder();
+        List<NextTableIds> nextIds = new ArrayList<>();
+        nextIds.add(new NextTableIdsBuilder().setTableId((short) 1).build());
+        nextIds.add(new NextTableIdsBuilder().setTableId((short) 2).build());
+        nextPropBuilder.setNextTableIds(nextIds);
+        propBuilder.addAugmentation(NextTableRelatedTableFeatureProperty.class, nextPropBuilder.build());
+        properties.add(propBuilder.build());
+        propBuilder = new TableFeaturePropertiesBuilder();
+        propBuilder.setType(TableFeaturesPropType.OFPTFPTNEXTTABLESMISS);
+        nextPropBuilder = new NextTableRelatedTableFeaturePropertyBuilder();
+        nextIds = new ArrayList<>();
+        nextPropBuilder.setNextTableIds(nextIds);
+        propBuilder.addAugmentation(NextTableRelatedTableFeatureProperty.class, nextPropBuilder.build());
+        properties.add(propBuilder.build());
+        propBuilder = new TableFeaturePropertiesBuilder();
+        propBuilder.setType(TableFeaturesPropType.OFPTFPTINSTRUCTIONS);
+        InstructionRelatedTableFeaturePropertyBuilder insPropBuilder =
+                new InstructionRelatedTableFeaturePropertyBuilder();
+        List<Instruction> insIds = new ArrayList<>();
+        InstructionBuilder insBuilder = new InstructionBuilder();
+        insBuilder.setType(WriteActions.class);
+        insIds.add(insBuilder.build());
+        insBuilder = new InstructionBuilder();
+        insBuilder.setType(GotoTable.class);
+        insIds.add(insBuilder.build());
+        insPropBuilder.setInstruction(insIds);
+        propBuilder.addAugmentation(InstructionRelatedTableFeatureProperty.class, insPropBuilder.build());
+        properties.add(propBuilder.build());
+        propBuilder = new TableFeaturePropertiesBuilder();
+        propBuilder.setType(TableFeaturesPropType.OFPTFPTINSTRUCTIONSMISS);
+        insPropBuilder = new InstructionRelatedTableFeaturePropertyBuilder();
+        insIds = new ArrayList<>();
+        insBuilder = new InstructionBuilder();
+        insBuilder.setType(WriteMetadata.class);
+        insIds.add(insBuilder.build());
+        insBuilder = new InstructionBuilder();
+        insBuilder.setType(ApplyActions.class);
+        insIds.add(insBuilder.build());
+        insBuilder = new InstructionBuilder();
+        insBuilder.setType(Meter.class);
+        insIds.add(insBuilder.build());
+        insBuilder = new InstructionBuilder();
+        insBuilder.setType(ClearActions.class);
+        insIds.add(insBuilder.build());
+        insBuilder = new InstructionBuilder();
+        insBuilder.setType(GotoTable.class);
+        insIds.add(insBuilder.build());
+        insPropBuilder.setInstruction(insIds);
+        propBuilder.addAugmentation(InstructionRelatedTableFeatureProperty.class, insPropBuilder.build());
+        properties.add(propBuilder.build());
+        tableFeaturesBuilder.setTableFeatureProperties(properties);
+        tableFeaturesList.add(tableFeaturesBuilder.build());
+        tableFeaturesBuilder = new TableFeaturesBuilder();
+        tableFeaturesBuilder.setTableId((short) 8);
+        tableFeaturesBuilder.setName("AAAABBBBCCCCDDDDEEEEFFFFGGGG");
+        tableFeaturesBuilder.setMetadataMatch(new BigInteger(new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}));
+        tableFeaturesBuilder.setMetadataWrite(new BigInteger(new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}));
+        tableFeaturesBuilder.setConfig(new TableConfig(true));
+        tableFeaturesBuilder.setMaxEntries(67L);
+        properties = new ArrayList<>();
+        propBuilder = new TableFeaturePropertiesBuilder();
+        propBuilder.setType(TableFeaturesPropType.OFPTFPTWRITEACTIONS);
+        ActionRelatedTableFeaturePropertyBuilder actBuilder = new ActionRelatedTableFeaturePropertyBuilder();
+        List<Action> actions = new ArrayList<>();
+        ActionBuilder actionBuilder = new ActionBuilder();
+        actionBuilder.setType(Output.class);
+        actions.add(actionBuilder.build());
+        actBuilder.setAction(actions);
+        propBuilder.addAugmentation(ActionRelatedTableFeatureProperty.class, actBuilder.build());
+        properties.add(propBuilder.build());
+        propBuilder = new TableFeaturePropertiesBuilder();
+        propBuilder.setType(TableFeaturesPropType.OFPTFPTWRITEACTIONSMISS);
+        actBuilder = new ActionRelatedTableFeaturePropertyBuilder();
+        actions = new ArrayList<>();
+        actBuilder.setAction(actions);
+        propBuilder.addAugmentation(ActionRelatedTableFeatureProperty.class, actBuilder.build());
+        properties.add(propBuilder.build());
+        propBuilder = new TableFeaturePropertiesBuilder();
+        propBuilder.setType(TableFeaturesPropType.OFPTFPTAPPLYACTIONS);
+        actBuilder = new ActionRelatedTableFeaturePropertyBuilder();
+        actions = new ArrayList<>();
+        actBuilder.setAction(actions);
+        propBuilder.addAugmentation(ActionRelatedTableFeatureProperty.class, actBuilder.build());
+        properties.add(propBuilder.build());
+        propBuilder = new TableFeaturePropertiesBuilder();
+        propBuilder.setType(TableFeaturesPropType.OFPTFPTAPPLYACTIONSMISS);
+        actBuilder = new ActionRelatedTableFeaturePropertyBuilder();
+        actions = new ArrayList<>();
+        actBuilder.setAction(actions);
+        propBuilder.addAugmentation(ActionRelatedTableFeatureProperty.class, actBuilder.build());
+        properties.add(propBuilder.build());
+        propBuilder = new TableFeaturePropertiesBuilder();
+        propBuilder.setType(TableFeaturesPropType.OFPTFPTMATCH);
+        OxmRelatedTableFeaturePropertyBuilder oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder();
+        List<MatchEntries> entries = new ArrayList<>();
+        MatchEntriesBuilder entriesBuilder = new MatchEntriesBuilder();
+        entriesBuilder.setOxmClass(OpenflowBasicClass.class);
+        entriesBuilder.setOxmMatchField(InPhyPort.class);
+        entriesBuilder.setHasMask(false);
+        entries.add(entriesBuilder.build());
+        entriesBuilder = new MatchEntriesBuilder();
+        entriesBuilder.setOxmClass(OpenflowBasicClass.class);
+        entriesBuilder.setOxmMatchField(InPort.class);
+        entriesBuilder.setHasMask(false);
+        entries.add(entriesBuilder.build());
+        oxmBuilder.setMatchEntries(entries);
+        propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build());
+        properties.add(propBuilder.build());
+        propBuilder = new TableFeaturePropertiesBuilder();
+        propBuilder.setType(TableFeaturesPropType.OFPTFPTWILDCARDS);
+        oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder();
+        entries = new ArrayList<>();
+        oxmBuilder.setMatchEntries(entries);
+        propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build());
+        properties.add(propBuilder.build());
+        propBuilder = new TableFeaturePropertiesBuilder();
+        propBuilder.setType(TableFeaturesPropType.OFPTFPTWRITESETFIELD);
+        oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder();
+        entries = new ArrayList<>();
+        oxmBuilder.setMatchEntries(entries);
+        propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build());
+        properties.add(propBuilder.build());
+        propBuilder = new TableFeaturePropertiesBuilder();
+        propBuilder.setType(TableFeaturesPropType.OFPTFPTWRITESETFIELDMISS);
+        oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder();
+        entries = new ArrayList<>();
+        oxmBuilder.setMatchEntries(entries);
+        propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build());
+        properties.add(propBuilder.build());
+        propBuilder = new TableFeaturePropertiesBuilder();
+        propBuilder.setType(TableFeaturesPropType.OFPTFPTAPPLYSETFIELD);
+        oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder();
+        entries = new ArrayList<>();
+        entriesBuilder = new MatchEntriesBuilder();
+        entriesBuilder.setOxmClass(OpenflowBasicClass.class);
+        entriesBuilder.setOxmMatchField(IpProto.class);
+        entriesBuilder.setHasMask(false);
+        entries.add(entriesBuilder.build());
+        entriesBuilder = new MatchEntriesBuilder();
+        entriesBuilder.setOxmClass(OpenflowBasicClass.class);
+        entriesBuilder.setOxmMatchField(IpEcn.class);
+        entriesBuilder.setHasMask(false);
+        entries.add(entriesBuilder.build());
+        oxmBuilder.setMatchEntries(entries);
+        propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build());
+        properties.add(propBuilder.build());
+        propBuilder = new TableFeaturePropertiesBuilder();
+        propBuilder.setType(TableFeaturesPropType.OFPTFPTAPPLYSETFIELDMISS);
+        oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder();
+        entries = new ArrayList<>();
+        oxmBuilder.setMatchEntries(entries);
+        propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build());
+        properties.add(propBuilder.build());
+        tableFeaturesBuilder.setTableFeatureProperties(properties);
+        tableFeaturesList.add(tableFeaturesBuilder.build());
+        featuresBuilder.setTableFeatures(tableFeaturesList);
+        caseBuilder.setMultipartRequestTableFeatures(featuresBuilder.build());
+        builder.setMultipartRequestBody(caseBuilder.build());
+        MultipartRequestInput message = builder.build();
+
+        ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer();
+        multipartFactory.serialize(message, out);
+
+        BufferHelper.checkHeaderV13(out, (byte) 18, 296);
+        Assert.assertEquals("Wrong type", 12, out.readUnsignedShort());
+        Assert.assertEquals("Wrong flags", 1, out.readUnsignedShort());
+        out.skipBytes(PADDING_IN_MULTIPART_REQUEST_MESSAGE);
+        Assert.assertEquals("Wrong length", 120, out.readUnsignedShort());
+        Assert.assertEquals("Wrong registry-id", 8, out.readUnsignedByte());
+        out.skipBytes(5);
+        Assert.assertEquals("Wrong name", "AAAABBBBCCCCDDDDEEEEFFFFGGGG",
+                ByteBufUtils.decodeNullTerminatedString(out, 32));
+        byte[] metadataMatch = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+        out.readBytes(metadataMatch);
+        Assert.assertArrayEquals("Wrong metadata-match",
+                new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}, metadataMatch);
+        byte[] metadataWrite = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+        out.readBytes(metadataWrite);
+        Assert.assertArrayEquals("Wrong metadata-write",
+                new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}, metadataWrite);
+        Assert.assertEquals("Wrong config", 8, out.readUnsignedInt());
+        Assert.assertEquals("Wrong max-entries", 65, out.readUnsignedInt());
+        Assert.assertEquals("Wrong property type", 2, out.readUnsignedShort());
+        Assert.assertEquals("Wrong property length", 6, out.readUnsignedShort());
+        Assert.assertEquals("Wrong next-registry-id", 1, out.readUnsignedByte());
+        Assert.assertEquals("Wrong next-registry-id", 2, out.readUnsignedByte());
+        out.skipBytes(2);
+        Assert.assertEquals("Wrong property type", 3, out.readUnsignedShort());
+        Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort());
+        out.skipBytes(4);
+        Assert.assertEquals("Wrong property type", 0, out.readUnsignedShort());
+        Assert.assertEquals("Wrong property length", 12, out.readUnsignedShort());
+        Assert.assertEquals("Wrong instruction type", 3, out.readUnsignedShort());
+        Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());
+        Assert.assertEquals("Wrong instruction type", 1, out.readUnsignedShort());
+        Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());
+        out.skipBytes(4);
+        Assert.assertEquals("Wrong property type", 1, out.readUnsignedShort());
+        Assert.assertEquals("Wrong property length", 24, out.readUnsignedShort());
+        Assert.assertEquals("Wrong instruction type", 2, out.readUnsignedShort());
+        Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());
+        Assert.assertEquals("Wrong instruction type", 4, out.readUnsignedShort());
+        Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());
+        Assert.assertEquals("Wrong instruction type", 6, out.readUnsignedShort());
+        Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());
+        Assert.assertEquals("Wrong instruction type", 5, out.readUnsignedShort());
+        Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());
+        Assert.assertEquals("Wrong instruction type", 1, out.readUnsignedShort());
+        Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());
+        Assert.assertEquals("Wrong length", 160, out.readUnsignedShort());
+        Assert.assertEquals("Wrong registry-id", 8, out.readUnsignedByte());
+        out.skipBytes(5);
+        Assert.assertEquals("Wrong name", "AAAABBBBCCCCDDDDEEEEFFFFGGGG",
+                ByteBufUtils.decodeNullTerminatedString(out, 32));
+        metadataMatch = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+        out.readBytes(metadataMatch);
+        Assert.assertArrayEquals("Wrong metadata-match",
+                new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}, metadataMatch);
+        metadataWrite = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+        out.readBytes(metadataWrite);
+        Assert.assertArrayEquals("Wrong metadata-write",
+                new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}, metadataWrite);
+        Assert.assertEquals("Wrong config", 8, out.readUnsignedInt());
+        Assert.assertEquals("Wrong max-entries", 67, out.readUnsignedInt());
+        Assert.assertEquals("Wrong property type", 4, out.readUnsignedShort());
+        Assert.assertEquals("Wrong property length", 8, out.readUnsignedShort());
+        Assert.assertEquals("Wrong action type", 0, out.readUnsignedShort());
+        Assert.assertEquals("Wrong action length", 4, out.readUnsignedShort());
+        Assert.assertEquals("Wrong property type", 5, out.readUnsignedShort());
+        Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort());
+        out.skipBytes(4);
+        Assert.assertEquals("Wrong property type", 6, out.readUnsignedShort());
+        Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort());
+        out.skipBytes(4);
+        Assert.assertEquals("Wrong property type", 7, out.readUnsignedShort());
+        Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort());
+        out.skipBytes(4);
+        Assert.assertEquals("Wrong property type", 8, out.readUnsignedShort());
+        Assert.assertEquals("Wrong property length", 12, out.readUnsignedShort());
+        Assert.assertEquals("Wrong match class", 0x8000, out.readUnsignedShort());
+        Assert.assertEquals("Wrong match field&mask", 2, out.readUnsignedByte());
+        Assert.assertEquals("Wrong match length", 4, out.readUnsignedByte());
+        Assert.assertEquals("Wrong match class", 0x8000, out.readUnsignedShort());
+        Assert.assertEquals("Wrong match field&mask", 0, out.readUnsignedByte());
+        Assert.assertEquals("Wrong match length", 4, out.readUnsignedByte());
+        out.skipBytes(4);
+        Assert.assertEquals("Wrong property type", 10, out.readUnsignedShort());
+        Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort());
+        out.skipBytes(4);
+        Assert.assertEquals("Wrong property type", 12, out.readUnsignedShort());
+        Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort());
+        out.skipBytes(4);
+        Assert.assertEquals("Wrong property type", 13, out.readUnsignedShort());
+        Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort());
+        out.skipBytes(4);
+        Assert.assertEquals("Wrong property type", 14, out.readUnsignedShort());
+        Assert.assertEquals("Wrong property length", 12, out.readUnsignedShort());
+        Assert.assertEquals("Wrong match class", 0x8000, out.readUnsignedShort());
+        Assert.assertEquals("Wrong match field&mask", 20, out.readUnsignedByte());
+        Assert.assertEquals("Wrong match length", 1, out.readUnsignedByte());
+        Assert.assertEquals("Wrong match class", 0x8000, out.readUnsignedShort());
+        Assert.assertEquals("Wrong match field&mask", 18, out.readUnsignedByte());
+        Assert.assertEquals("Wrong match length", 1, out.readUnsignedByte());
+        out.skipBytes(4);
+        Assert.assertEquals("Wrong property type", 15, out.readUnsignedShort());
+        Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort());
+        out.skipBytes(4);
+        Assert.assertTrue("Unread data", out.readableBytes() == 0);
+    }
+
+    /**
+     * @throws Exception
+     * Testing of {@link MultipartRequestInputFactory} for correct translation from POJO
+     */
+    @Test
+    public void testMultipartRequestTableFeaturesExperimenter() throws Exception {
+        MultipartRequestInputFactory factory = new MultipartRequestInputFactory();
+        factory.injectSerializerRegistry(mockRegistry);
+        MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder();
+        BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID);
+        builder.setType(MultipartType.forValue(12));
+        builder.setFlags(new MultipartRequestFlags(true));
+        MultipartRequestTableFeaturesCaseBuilder caseBuilder = new MultipartRequestTableFeaturesCaseBuilder();
+        MultipartRequestTableFeaturesBuilder featuresBuilder = new MultipartRequestTableFeaturesBuilder();
+        List<TableFeatures> tableFeaturesList = new ArrayList<>();
+        TableFeaturesBuilder tableFeaturesBuilder = new TableFeaturesBuilder();
+        tableFeaturesBuilder.setTableId((short) 8);
+        tableFeaturesBuilder.setName("AAAABBBBCCCCDDDDEEEEFFFFGGGG");
+        tableFeaturesBuilder.setMetadataMatch(new BigInteger(new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}));
+        tableFeaturesBuilder.setMetadataWrite(new BigInteger(new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}));
+        tableFeaturesBuilder.setConfig(new TableConfig(true));
+        tableFeaturesBuilder.setMaxEntries(65L);
+        List<TableFeatureProperties> properties = new ArrayList<>();
+        TableFeaturePropertiesBuilder propBuilder = new TableFeaturePropertiesBuilder();
+        propBuilder.setType(TableFeaturesPropType.OFPTFPTEXPERIMENTER);
+        ExperimenterIdTableFeaturePropertyBuilder expBuilder = new ExperimenterIdTableFeaturePropertyBuilder();
+        expBuilder.setExperimenter(new ExperimenterId(42L));
+        propBuilder.addAugmentation(ExperimenterIdTableFeatureProperty.class, expBuilder.build());
+        properties.add(propBuilder.build());
+        propBuilder = new TableFeaturePropertiesBuilder();
+        propBuilder.setType(TableFeaturesPropType.OFPTFPTEXPERIMENTERMISS);
+        expBuilder = new ExperimenterIdTableFeaturePropertyBuilder();
+        expBuilder.setExperimenter(new ExperimenterId(43L));
+        propBuilder.addAugmentation(ExperimenterIdTableFeatureProperty.class, expBuilder.build());
+        properties.add(propBuilder.build());
+        tableFeaturesBuilder.setTableFeatureProperties(properties);
+        tableFeaturesList.add(tableFeaturesBuilder.build());
+        featuresBuilder.setTableFeatures(tableFeaturesList);
+        caseBuilder.setMultipartRequestTableFeatures(featuresBuilder.build());
+        builder.setMultipartRequestBody(caseBuilder.build());
+        MultipartRequestInput message = builder.build();
+
+        ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer();
+        factory.serialize(message, out);
+
+        BufferHelper.checkHeaderV13(out, (byte) 18, 80);
+        Assert.assertEquals("Wrong type", 12, out.readUnsignedShort());
+        Assert.assertEquals("Wrong flags", 1, out.readUnsignedShort());
+        out.skipBytes(PADDING_IN_MULTIPART_REQUEST_MESSAGE);
+        Assert.assertEquals("Wrong length", 64, out.readUnsignedShort());
+        Assert.assertEquals("Wrong registry-id", 8, out.readUnsignedByte());
+        out.skipBytes(5);
+        Assert.assertEquals("Wrong name", "AAAABBBBCCCCDDDDEEEEFFFFGGGG",
+                ByteBufUtils.decodeNullTerminatedString(out, 32));
+        byte[] metadataMatch = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+        out.readBytes(metadataMatch);
+        Assert.assertArrayEquals("Wrong metadata-match",
+                new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}, metadataMatch);
+        byte[] metadataWrite = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+        out.readBytes(metadataWrite);
+        Assert.assertArrayEquals("Wrong metadata-write",
+                new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}, metadataWrite);
+        Assert.assertEquals("Wrong config", 8, out.readUnsignedInt());
+        Assert.assertEquals("Wrong max-entries", 65, out.readUnsignedInt());
+        Mockito.verify(serializer, Mockito.times(2)).serialize(Matchers.any(TableFeatureProperties.class),
+                Matchers.any(ByteBuf.class));
+    }
 }
\ No newline at end of file