diff --git a/.github/workflows/install-tests.yml b/.github/workflows/install-tests.yml
index 660da4a8bd7cbe0622d3307a99f7de9a4ac7fb38_LmdpdGh1Yi93b3JrZmxvd3MvaW5zdGFsbC10ZXN0cy55bWw=..4db15d6e3210fb6ad82774413d3499ed5625f8d4_LmdpdGh1Yi93b3JrZmxvd3MvaW5zdGFsbC10ZXN0cy55bWw= 100644
--- a/.github/workflows/install-tests.yml
+++ b/.github/workflows/install-tests.yml
@@ -11,8 +11,9 @@
       matrix:
         environment: ['macos-latest', 'windows-latest', 'ubuntu-latest']
         python-version: [2.7, 3.5, 3.6, 3.7, 3.8]
+        python-architecture: ['x86', 'x64']
         mq-client-version: [9.1.5.0]
         exclude:
           # Windows runner does not have libraries required for build with python2.7
           - environment: windows-latest
             python-version: 2.7
@@ -14,8 +15,13 @@
         mq-client-version: [9.1.5.0]
         exclude:
           # Windows runner does not have libraries required for build with python2.7
           - environment: windows-latest
             python-version: 2.7
+          # actions/setup-python does not have x86 versions for ubuntu and macos
+          - environment: ubuntu-latest
+            python-architecture: 'x86'
+          - environment: macos-latest
+            python-architecture: 'x86'
     runs-on: ${{ matrix.environment}}
     steps:
       - name: Checkout source
@@ -34,6 +40,6 @@
           mq-client-version: ${{ matrix.mq-client-version }}
 
       - name: Setup python ${{ matrix.python-version }}
-        uses: actions/setup-python@v1
+        uses: actions/setup-python@v2
         with:
           python-version: ${{ matrix.python-version }}
@@ -38,5 +44,6 @@
         with:
           python-version: ${{ matrix.python-version }}
+          architecture: ${{ matrix.python-architecture }}
 
       - name: Install pymqi
         env:
diff --git a/code/README b/code/README
index 660da4a8bd7cbe0622d3307a99f7de9a4ac7fb38_Y29kZS9SRUFETUU=..4db15d6e3210fb6ad82774413d3499ed5625f8d4_Y29kZS9SRUFETUU= 100644
--- a/code/README
+++ b/code/README
@@ -62,6 +62,9 @@
 * As a prerequisite, you first need to install an IBM MQ client in the system that PyMQI is about to be installed;
   it is a free library offered by IBM on top of which higher-level ones, such as PyMQI, can connect to queue managers.
   IBM MQ clients can be downloaded from IBM's website.
+ 
+* Prerequisite for Windows: Microsoft Visual C++ compiler.
+  Each Python version uses a specific compiler version. So, you need to install the compiler version that corresponds to your Python version : https://wiki.python.org/moin/WindowsCompilers
 
 * Now you can use pip to install PyMQI itself:
 
diff --git a/code/pymqi/__init__.py b/code/pymqi/__init__.py
index 660da4a8bd7cbe0622d3307a99f7de9a4ac7fb38_Y29kZS9weW1xaS9fX2luaXRfXy5weQ==..4db15d6e3210fb6ad82774413d3499ed5625f8d4_Y29kZS9weW1xaS9fX2luaXRfXy5weQ== 100644
--- a/code/pymqi/__init__.py
+++ b/code/pymqi/__init__.py
@@ -2986,6 +2986,24 @@
                     parameter = CFBS(StringLength=parameter.StringLength)
                     parameter.unpack(message[cursor:cursor + parameter.StrucLength])
                 value = parameter.String
+            elif parameter_type == CMQCFC.MQCFT_STRING_FILTER:
+                parameter = CFSF()
+                parameter.unpack(message[cursor:cursor + CMQCFC.MQCFSF_STRUC_LENGTH_FIXED])
+                if parameter.FilterValueLength > 0:
+                    parameter = CFSF(FilterValueLength=parameter.FilterValueLength)
+                    parameter.unpack(message[cursor:cursor + CMQCFC.MQCFSF_STRUC_LENGTH_FIXED + parameter.FilterValueLength])
+                value = (parameter.Operator, parameter.FilterValue)
+            elif parameter_type == CMQCFC.MQCFT_BYTE_STRING_FILTER:
+                parameter = CFBF()
+                parameter.unpack(message[cursor:cursor + CMQCFC.MQCFBF_STRUC_LENGTH_FIXED])
+                if parameter.FilterValueLength > 0:
+                    parameter = CFBF(FilterValueLength=parameter.FilterValueLength)
+                    parameter.unpack(message[cursor:cursor + CMQCFC.MQCFBF_STRUC_LENGTH_FIXED + parameter.FilterValueLength])
+                value = (parameter.Operator, parameter.FilterValue)
+            elif parameter_type == CMQCFC.MQCFT_INTEGER_FILTER:
+                parameter = CFIF()
+                parameter.unpack(message[cursor:cursor + CMQCFC.MQCFIF_STRUC_LENGTH])
+                value = (parameter.Operator, parameter.FilterValue)
             else:
                 pcf_type = struct.unpack(MQLONG_TYPE, message[cursor:cursor + 4])
                 raise NotImplementedError('Unpack for type ({}) not implemented'.format(pcf_type))
diff --git a/code/tests/messages/pcf_with_cfif.dat b/code/tests/messages/pcf_with_cfif.dat
new file mode 100644
index 0000000000000000000000000000000000000000..3cb8714fa57da95f20cae85d74559e4c50d647f7
GIT binary patch
literal 284
zc$|gLu?_)I6olb#U2Fu2LZP#TN+t0Ggi;~Afz}q@SR)dxS|TUAE8CgmH0RDgXKs!K
z5-!N<f$M+{rkG$er>mL*k0I;C2<5FT8bwz4->J$9{|?XEzrx{o-k;7t<gc2{Ph#Ba
kv~6{o;htCB<L)x+XAKwr*fnhIg9-I&_LZvt##`ik0maZ1K>z>%

diff --git a/code/tests/messages/pcf_with_cfsf.dat b/code/tests/messages/pcf_with_cfsf.dat
new file mode 100644
index 0000000000000000000000000000000000000000..287e01b35bcfc99ffba3affeebd56f5efcb0f2ca
GIT binary patch
literal 296
zc$|gLy=nqs5QX7q^Jy0G2MHGGv`A$ocm;}<78373>|!B$yMj#+Y^?<u_S;~W0|UeG
z&Y3eMzL2m*kt_7m;td1zF&olQ)d;_Bril*rhyAElcm;n?l~?c!Tr)qxYQ0&0Z~j*P
zRqgpmbYC*fUow5-QdZgH?zng_>b>A&*2~$?B_H|ECQiHKX`K7;xuxp&;KK6>5>Xfp

diff --git a/code/tests/test_base_api.py b/code/tests/test_base_api.py
index 660da4a8bd7cbe0622d3307a99f7de9a4ac7fb38_Y29kZS90ZXN0cy90ZXN0X2Jhc2VfYXBpLnB5..4db15d6e3210fb6ad82774413d3499ed5625f8d4_Y29kZS90ZXN0cy90ZXN0X2Jhc2VfYXBpLnB5 100644
--- a/code/tests/test_base_api.py
+++ b/code/tests/test_base_api.py
@@ -312,17 +312,6 @@
         self.assertEqual(md.Format, pymqi.CMQC.MQFMT_STRING)
         self.assertEqual(md.CodedCharSetId, 1208)
 
-    def test_put1_bytes(self):
-        md = pymqi.MD()
-        self.qmgr.put1(self.queue_name, b'\xd1\x82\xd0\xb5\xd1\x81\xd1\x82', md)  # Non-ascii characters
-
-        gmo = pymqi.GMO()
-        gmo.Options = gmo.Options & ~ pymqi.CMQC.MQGMO_CONVERT
-        message = self.queue.get(None, md, gmo)
-
-        self.assertEqual(message, b'\xd1\x82\xd0\xb5\xd1\x81\xd1\x82')
-        self.assertEqual(md.Format, pymqi.CMQC.MQFMT_NONE)
-
     def test_put1(self):
         input_msg = b'Hello world!'
         self.qmgr.put1(self.queue_name, input_msg)
diff --git a/code/tests/test_pcf.py b/code/tests/test_pcf.py
index 660da4a8bd7cbe0622d3307a99f7de9a4ac7fb38_Y29kZS90ZXN0cy90ZXN0X3BjZi5weQ==..4db15d6e3210fb6ad82774413d3499ed5625f8d4_Y29kZS90ZXN0cy90ZXN0X3BjZi5weQ== 100644
--- a/code/tests/test_pcf.py
+++ b/code/tests/test_pcf.py
@@ -1,4 +1,6 @@
 """Test PCF usage."""
 import os
+from sys import version_info as sys_version_info
+
 from unittest import skip
 from unittest import skipIf
@@ -3,4 +5,4 @@
 from unittest import skip
 from unittest import skipIf
-from ddt import data
+from ddt import data  # type: ignore
 from ddt import ddt
@@ -6,5 +8,9 @@
 from ddt import ddt
-from sys import version_info as sys_version_info
+
+try:
+    from typing import List
+except ImportError:
+    pass
 
 from test_setup import Tests  # noqa
 from test_setup import main  # noqa
@@ -15,7 +21,6 @@
 class TestPCF(Tests):
     """Class for MQ PCF testing."""
 
-    pcf = None
     messages_dir = os.path.join(os.path.dirname(__file__), "messages")
 
     @classmethod
@@ -44,7 +49,7 @@
 
         super(TestPCF, self).tearDown()
 
-    @skip('Not implemented')
+    @skip('Test not implemented')
     def test_mqcfbf(self):
         """Test MQCFBF PCF byte string filter parameter."""
 
@@ -53,7 +58,7 @@
 
         Also uses MQCFIN and MQCFIL as parameters
         """
-        attrs = []
+        attrs = []  # type: List[pymqi.MQOpts]
         attrs.append(pymqi.CFBS(Parameter=pymqi.CMQCFC.MQBACF_GENERIC_CONNECTION_ID,
                                 String=b''))
         attrs.append(pymqi.CFIN(Parameter=pymqi.CMQCFC.MQIACF_CONN_INFO_TYPE,
@@ -76,7 +81,7 @@
 
         Also uses MQCFST, MQCFIN and MQCFIL as parameters
         """
-        attrs = []
+        attrs = []  # type: List[pymqi.MQOpts]
         attrs.append(pymqi.CFST(Parameter=pymqi.CMQC.MQCA_Q_NAME,
                                 String=b'*'))
         attrs.append(pymqi.CFIN(Parameter=pymqi.CMQC.MQIA_Q_TYPE,
@@ -101,7 +106,7 @@
 
         Also uses MQCFST, MQCFIN and MQCFIL as parameters
         """
-        attrs = []
+        attrs = []  # type: List[pymqi.MQOpts]
         attrs.append(pymqi.CFST(Parameter=pymqi.CMQC.MQCA_Q_NAME,
                                 String=b'*'))
         attrs.append(pymqi.CFIN(Parameter=pymqi.CMQC.MQIA_Q_TYPE,
@@ -130,7 +135,7 @@
 
         Also uses MQCFST and MQCFIN as parameters
         """
-        attrs = []
+        attrs = []  # type: List[pymqi.MQOpts]
         attrs.append(pymqi.CFST(Parameter=pymqi.CMQC.MQCA_NAMELIST_NAME,
                                 String='{}NAMELIST'.format(self.prefix).encode()))
         attrs.append(pymqi.CFSL(Parameter=pymqi.CMQC.MQCA_NAMES,
@@ -187,5 +192,5 @@
         get_md = pymqi.MD(MsgId=put_md.MsgId)  # pylint: disable=no-member
         message = queue.get(None, get_md, get_opts)
         queue.close()
-        message = pymqi.PCFExecute.unpack(message)
+        unpacked_message = pymqi.PCFExecute.unpack(message)
 
@@ -191,4 +196,4 @@
 
-        self.assertTrue(isinstance(message[0][1], list),
-                        'Returned value is not list: {}'.format(type(message[0][1])))
+        self.assertTrue(isinstance(unpacked_message[0][1], list),
+                        'Returned value is not list: {}'.format(type(unpacked_message[0][1])))
 
@@ -194,3 +199,3 @@
 
-        self.assertTrue(len(message[0][1]) == len(value), 'List length is different!')
+        self.assertTrue(len(unpacked_message[0][1]) == len(value), 'List length is different!')
 
@@ -196,5 +201,5 @@
 
-        for item in message[0][1]:
+        for item in unpacked_message[0][1]:
             self.assertTrue(item in value, '{} value not in values list'.format(item))
             value.remove(item)
 
@@ -204,6 +209,6 @@
                             Type=pymqi.CMQCFC.MQCFT_USER,
                             ParameterCount=4).pack()
         message += pymqi.CFST(Parameter=pymqi.CMQC.MQCA_Q_MGR_NAME,
-                                    String=b'QM1').pack()
+                              String=b'QM1').pack()
         # group1
         message += pymqi.CFGR(Parameter=pymqi.CMQCFC.MQGACF_Q_STATISTICS_DATA,
@@ -208,4 +213,4 @@
         # group1
         message += pymqi.CFGR(Parameter=pymqi.CMQCFC.MQGACF_Q_STATISTICS_DATA,
-                                    ParameterCount=3).pack()
+                              ParameterCount=3).pack()
         message += pymqi.CFST(Parameter=pymqi.CMQC.MQCA_Q_NAME,
@@ -211,3 +216,3 @@
         message += pymqi.CFST(Parameter=pymqi.CMQC.MQCA_Q_NAME,
-                                    String=b'SYSTEM.ADMIN.COMMAND.QUEUE').pack()
+                              String=b'SYSTEM.ADMIN.COMMAND.QUEUE').pack()
         message += pymqi.CFIN64(Parameter=pymqi.CMQCFC.MQIAMO_Q_MIN_DEPTH,
@@ -213,3 +218,3 @@
         message += pymqi.CFIN64(Parameter=pymqi.CMQCFC.MQIAMO_Q_MIN_DEPTH,
-                                    Value=10).pack()
+                                Value=10).pack()
         message += pymqi.CFIL64(Parameter=pymqi.CMQCFC.MQIAMO64_AVG_Q_TIME,
@@ -215,4 +220,4 @@
         message += pymqi.CFIL64(Parameter=pymqi.CMQCFC.MQIAMO64_AVG_Q_TIME,
-                                    Values=[1, 2, 3]).pack()
+                                Values=[1, 2, 3]).pack()
         # group2
         message += pymqi.CFGR(Parameter=pymqi.CMQCFC.MQGACF_Q_STATISTICS_DATA,
@@ -217,4 +222,4 @@
         # group2
         message += pymqi.CFGR(Parameter=pymqi.CMQCFC.MQGACF_Q_STATISTICS_DATA,
-                                    ParameterCount=3).pack()
+                              ParameterCount=3).pack()
         message += pymqi.CFST(Parameter=pymqi.CMQC.MQCA_Q_NAME,
@@ -220,3 +225,3 @@
         message += pymqi.CFST(Parameter=pymqi.CMQC.MQCA_Q_NAME,
-                                    String=b'SYSTEM.ADMIN.COMMAND.QUEUE2').pack()
+                              String=b'SYSTEM.ADMIN.COMMAND.QUEUE2').pack()
         message += pymqi.CFIN64(Parameter=pymqi.CMQCFC.MQIAMO_Q_MIN_DEPTH,
@@ -222,3 +227,3 @@
         message += pymqi.CFIN64(Parameter=pymqi.CMQCFC.MQIAMO_Q_MIN_DEPTH,
-                                    Value=20).pack()
+                                Value=20).pack()
         message += pymqi.CFIL64(Parameter=pymqi.CMQCFC.MQIAMO64_AVG_Q_TIME,
@@ -224,5 +229,5 @@
         message += pymqi.CFIL64(Parameter=pymqi.CMQCFC.MQIAMO64_AVG_Q_TIME,
-                                    Values=[111, 222]).pack()
+                                Values=[111, 222]).pack()
 
         message += pymqi.CFST(Parameter=pymqi.CMQCFC.MQCAMO_START_TIME,
                               String=b'10.41.58').pack()
@@ -266,7 +271,7 @@
                             Command=pymqi.CMQCFC.MQCMD_STATISTICS_Q,
                             ParameterCount=1).pack()
         message += pymqi.CFST(Parameter=pymqi.CMQC.MQCA_Q_MGR_NAME,
-                                    String=b'QM1').pack()
+                              String=b'QM1').pack()
 
         queue = pymqi.Queue(self.qmgr, self.queue_name,
                             pymqi.CMQC.MQOO_INPUT_AS_Q_DEF + pymqi.CMQC.MQOO_OUTPUT)
@@ -283,8 +288,8 @@
         queue.close()
         message, header = pymqi.PCFExecute.unpack(message)
 
-        self.assertEqual(header.Command,  pymqi.CMQCFC.MQCMD_STATISTICS_Q)
-        self.assertEqual(header.Type,  pymqi.CMQCFC.MQCFT_STATISTICS)
+        self.assertEqual(header.Command, pymqi.CMQCFC.MQCMD_STATISTICS_Q)  # pylint: disable=no-member
+        self.assertEqual(header.Type, pymqi.CMQCFC.MQCFT_STATISTICS)  # pylint: disable=no-member
 
         self.assertEqual({
             pymqi.CMQC.MQCA_Q_MGR_NAME: b'QM1\x00',
@@ -292,5 +297,14 @@
 
     def test_unpack_group(self):
         """Test parameters group unpack."""
-        binary_message = open(os.path.join(self.messages_dir, "statistics_q.dat"), "rb").read()
+        with open(os.path.join(self.messages_dir, "statistics_q.dat"), "rb") as file:
+            binary_message = file.read()
+            message, header = pymqi.PCFExecute.unpack(binary_message)
+
+            self.assertEqual(header.Command, pymqi.CMQCFC.MQCMD_STATISTICS_Q)  # pylint: disable=no-member
+            self.assertEqual(header.Type, pymqi.CMQCFC.MQCFT_STATISTICS)  # pylint: disable=no-member
+
+            self.assertEqual(message[pymqi.CMQC.MQCA_Q_MGR_NAME].strip(), b'mq_mgr1')
+            self.assertEqual(message[pymqi.CMQCFC.MQCAMO_START_DATE], b'2020-06-15\x00\x00')
+            self.assertEqual(len(message[pymqi.CMQCFC.MQGACF_Q_STATISTICS_DATA]), 16)
 
@@ -296,3 +310,5 @@
 
-        message, header = pymqi.PCFExecute.unpack(binary_message)
+            item = message[pymqi.CMQCFC.MQGACF_Q_STATISTICS_DATA][0]
+            self.assertEqual(item[pymqi.CMQC.MQCA_Q_NAME].strip(), b'SYSTEM.ADMIN.COMMAND.QUEUE')
+            self.assertEqual(item[pymqi.CMQCFC.MQIAMO_PUTS], [14, 0])
 
@@ -298,4 +314,8 @@
 
-        self.assertEqual(header.Command,  pymqi.CMQCFC.MQCMD_STATISTICS_Q)
-        self.assertEqual(header.Type,  pymqi.CMQCFC.MQCFT_STATISTICS)
+    def test_unpack_cfsf(self):
+        """Test unpack of PCF message with MQCFSF structure."""
+        with open(os.path.join(self.messages_dir, "pcf_with_cfsf.dat"), "rb") as file:
+            binary_message = file.read()
+
+            message, _ = pymqi.PCFExecute.unpack(binary_message)
 
@@ -301,5 +321,13 @@
 
-        self.assertEqual(message[pymqi.CMQC.MQCA_Q_MGR_NAME].strip(), b'mq_mgr1')
-        self.assertEqual(message[pymqi.CMQCFC.MQCAMO_START_DATE], b'2020-06-15\x00\x00')
-        self.assertEqual(len(message[pymqi.CMQCFC.MQGACF_Q_STATISTICS_DATA]), 16)
+        self.assertEqual(message.get(pymqi.CMQCFC.MQGACF_COMMAND_DATA, [{}])[0].get(pymqi.CMQC.MQCA_Q_DESC)[0],
+                         pymqi.CMQCFC.MQCFOP_LIKE)
+
+        self.assertEqual(message.get(pymqi.CMQCFC.MQGACF_COMMAND_DATA,
+                                     [{}])[0].get(pymqi.CMQC.MQCA_Q_DESC)[1].rstrip(b'\x00'),
+                         b'test*')
+
+    @skip('Test not implemented')
+    def test_unpack_cfbf(self):
+        """Test unpack of PCF message with MQCFBF structure."""
+
 
@@ -305,5 +333,6 @@
 
-        item = message[pymqi.CMQCFC.MQGACF_Q_STATISTICS_DATA][0]
-        self.assertEqual(item[pymqi.CMQC.MQCA_Q_NAME].strip(), b'SYSTEM.ADMIN.COMMAND.QUEUE')
-        self.assertEqual(item[pymqi.CMQCFC.MQIAMO_PUTS], [14, 0])
+    def test_unpack_cfif(self):
+        """Test unpack of PCF message with MQCFIF structure."""
+        with open(os.path.join(self.messages_dir, "pcf_with_cfif.dat"), "rb") as file:
+            binary_message = file.read()
 
@@ -309,5 +338,11 @@
 
-    @skipIf(sys_version_info < (3, 7),'Python pre 3.7 issues: https://github.com/dsuch/pymqi/issues/207#issuecomment-645422229')
+            message, _ = pymqi.PCFExecute.unpack(binary_message)
+
+        self.assertEqual(message.get(pymqi.CMQCFC.MQGACF_COMMAND_DATA, [{}])[0].get(pymqi.CMQC.MQIA_CURRENT_Q_DEPTH),
+                         (pymqi.CMQCFC.MQCFOP_GREATER, 0))
+
+    @skipIf(sys_version_info < (3, 7),
+            'Python pre 3.7 issues: https://github.com/dsuch/pymqi/issues/207#issuecomment-645422229')
     def test_mqcfbs_old(self):
         """Test byte string MQCFBS with old style."""
         attrs = {
@@ -317,7 +352,7 @@
         }
         fltr = pymqi.Filter(pymqi.CMQC.MQIA_APPL_TYPE).equal(pymqi.CMQC.MQAT_USER)
 
-        results = self.pcf.MQCMD_INQUIRE_CONNECTION(attrs) #, [fltr])
+        results = self.pcf.MQCMD_INQUIRE_CONNECTION(attrs, [fltr])
 
         self.assertGreater(len(results), 0)
 
diff --git a/code/tests/test_setup.py b/code/tests/test_setup.py
index 660da4a8bd7cbe0622d3307a99f7de9a4ac7fb38_Y29kZS90ZXN0cy90ZXN0X3NldHVwLnB5..4db15d6e3210fb6ad82774413d3499ed5625f8d4_Y29kZS90ZXN0cy90ZXN0X3NldHVwLnB5 100644
--- a/code/tests/test_setup.py
+++ b/code/tests/test_setup.py
@@ -23,7 +23,8 @@
 
     prefix = ''
 
-    qmgr = None
+    qmgr = None  # type: pymqi.QueueManager
+    pcf = None  # type: pymqi.PCFExecute
 
 
     @classmethod
@@ -49,7 +50,7 @@
             cls.qmgr.connectTCPClient(cls.queue_manager, pymqi.CD(), cls.channel,
                                       cls.conn_info, cls.user, cls.password)
 
-        cls.pcf = pymqi.PCFExecute(cls.qmgr, response_wait_interval=5000)
+        cls.pcf = pymqi.PCFExecute(cls.qmgr, response_wait_interval=15000)
 
         cls.version = cls.inquire_qmgr_version().decode()