checkQueryParams(requestUrl, transactionPathPrefix, schemaPath, components, options,
    schemaCache, jsonSchemaDialect, callback) {
    let parsedUrl = require('url').parse(requestUrl),
      schemaParams = _.filter(schemaPath.parameters, (param) => { return param.in === 'query'; }),
      requestQueryArray = [],
      requestQueryParams = [],
      resolvedSchemaParams = [],
      mismatchProperty = 'QUERYPARAM',
      securityParams,
      urlMalformedError;

    if (options.validationPropertiesToIgnore.includes(mismatchProperty)) {
      return callback(null, []);
    }

    if (!parsedUrl.query) {
      // null query params should be treated as lack of any params
      parsedUrl.query = '';
    }
    requestQueryArray = parsedUrl.query.split('&');

    _.each(requestQueryArray, (rqp) => {
      let parts = rqp.split('='),
        qKey, qVal;

      try {
        qKey = decodeURIComponent(parts[0]);
        qVal = decodeURIComponent(parts.slice(1).join('='));
      }
      catch (err) {
        return (urlMalformedError = err);
      }


      if (qKey.length > 0) {
        requestQueryParams.push({
          key: qKey,
          value: qVal
        });
      }
    });

    if (urlMalformedError) {
      return callback(urlMalformedError);
    }

    // filter out query params added by security schemes
    securityParams = _.map(this.getSecurityParams(_.get(components, 'components'), 'query'), 'name');
    requestQueryParams = _.filter(requestQueryParams, (pQuery) => {
      return !_.includes(securityParams, pQuery.key);
    });

    // resolve schema params
    // below will make sure for exploded params actual schema of property present in collection is present
    _.forEach(schemaParams, (param) => {
      let pathPrefix = param.pathPrefix,
        paramSchema = deref.resolveRefs(_.cloneDeep(param.schema), PARAMETER_SOURCE.REQUEST, components, {}),
        { style, explode } = this.getParamSerialisationInfo(param, PARAMETER_SOURCE.REQUEST, components),
        isPropSeparable = _.includes(['form', 'deepObject'], style);

      if (isPropSeparable && paramSchema.type === 'array' && explode) {
        /**
         * avoid validation of complex array type param as OAS doesn't define serialisation
         * of Array with deepObject style
         */
        if (!_.includes(['array', 'object'], _.get(paramSchema, 'items.type'))) {
          // add schema of corresponding items instead array
          resolvedSchemaParams.push(_.assign({}, param, {
            schema: _.get(paramSchema, 'items'),
            isResolvedParam: true
          }));
        }
      }
      else if (isPropSeparable && paramSchema.type === 'object' && explode) {
        // resolve all child params of parent param with deepObject style
        if (style === 'deepObject') {
          resolvedSchemaParams = _.concat(resolvedSchemaParams, this.extractChildParamSchema(paramSchema,
            param.name, { required: _.get(param, 'required'), pathPrefix, description: _.get(param, 'description') }));
        }
        else {
          // add schema of all properties instead entire object
          _.forEach(_.get(paramSchema, 'properties', {}), (propSchema, propName) => {
            resolvedSchemaParams.push({
              name: propName,
              schema: propSchema,
              required: _.get(param, 'required') || false,
              description: _.get(param, 'description'),
              isResolvedParam: true,
              pathPrefix
            });
          });
        }
      }
      else {
        resolvedSchemaParams.push(param);
      }
    });

    return async.map(requestQueryParams, (pQuery, cb) => {
      let mismatches = [],
        index = _.findIndex(requestQueryParams, pQuery),
        resolvedParamValue = pQuery.value;

      const schemaParam = _.find(resolvedSchemaParams, (param) => { return param.name === pQuery.key; });

      if (!schemaParam) {
        // skip validation of complex array params
        if (this.isParamComplexArray(pQuery.key)) {
          return cb(null, mismatches);
        }
        if (options.showMissingInSchemaErrors) {
          mismatches.push({
            property: mismatchProperty,
            transactionJsonPath: transactionPathPrefix + `[${index}]`,
            schemaJsonPath: null,
            reasonCode: 'MISSING_IN_SCHEMA',
            reason: `The query parameter ${pQuery.key} was not found in the schema`
          });
        }
        return cb(null, mismatches);
      }

      // assign parameter example(s) as schema examples;
      this.assignParameterExamples(schemaParam);

      if (!schemaParam.isResolvedParam) {
        resolvedParamValue = this.deserialiseParamValue(schemaParam, pQuery.value, PARAMETER_SOURCE.REQUEST,
          components, schemaCache);
      }

      // query found in spec. check query's schema
      setTimeout(() => {
        if (!schemaParam.schema) {
          // no errors to show if there's no schema present in the spec
          return cb(null, []);
        }
        this.checkValueAgainstSchema(mismatchProperty,
          transactionPathPrefix + `[${index}].value`,
          pQuery.key,
          resolvedParamValue,
          schemaParam.pathPrefix + '[?(@.name==\'' + schemaParam.name + '\')]',
          schemaParam.schema,
          PARAMETER_SOURCE.REQUEST,
          components, options, schemaCache, jsonSchemaDialect, cb
        );
      }, 0);
    }, (err, res) => {
      let mismatches = [],
        mismatchObj;

      _.each(_.filter(resolvedSchemaParams, (q) => { return q.required; }), (qp) => {
        if (!_.find(requestQueryParams, (param) => {
          return param.key === qp.name;
        })) {

          // assign parameter example(s) as schema examples;
          this.assignParameterExamples(qp);

          mismatchObj = {
            property: mismatchProperty,
            transactionJsonPath: transactionPathPrefix,
            schemaJsonPath: qp.pathPrefix + '[?(@.name==\'' + qp.name + '\')]',
            reasonCode: 'MISSING_IN_REQUEST',
            reason: `The required query parameter "${qp.name}" was not found in the transaction`
          };

          if (options.suggestAvailableFixes) {
            mismatchObj.suggestedFix = {
              key: qp.name,
              actualValue: null,
              suggestedValue: {
                key: qp.name,
                value: safeSchemaFaker(qp.schema || {}, 'example', PROCESSING_TYPE.VALIDATION,
                  PARAMETER_SOURCE.REQUEST, components, SCHEMA_FORMATS.DEFAULT, schemaCache, options),
                description: this.getParameterDescription(qp)
              }
            };
          }
          mismatches.push(mismatchObj);
        }
      });
      return callback(null, _.concat(_.flatten(res), mismatches));
    });
  }
Collection stores empty description as null, while OpenAPI spec can have empty string as description.
Hence We need to treat null and empty string as match. So check first if both schema and collection description
are not empty. _.isEmpty() returns true for null/undefined/''(empty string)
i.e. collection desc = null and schema desc = '', for this case no mismatch will occurr