void
  xml_compiler::remapclasses_initialize_vector_loader::add_to_initialize_vector(const std::string& params,
                                                                                uint32_t type) const
  {
    size_t count_index = remapclasses_initialize_vector_.size();
    uint32_t count = 0;

    remapclasses_initialize_vector_.push_back(0); // count

    remapclasses_initialize_vector_.push_back(type);
    ++count;

    pqrs::string::tokenizer tokenizer_comma(params, ',');
    std::string arg;
    std::string value;
    while (tokenizer_comma.split_removing_empty(arg)) {
      unsigned int datatype = 0;
      unsigned int newvalue = 0;

      pqrs::string::tokenizer tokenizer_pipe(arg, '|');
      while (tokenizer_pipe.split_removing_empty(value)) {
        unsigned int newdatatype = xml_compiler_utilities::get_datatype(value);
        if (newdatatype == BRIDGE_DATATYPE_NONE) {
          throw xml_compiler_runtime_error("Unknown symbol:\n\n" + value);
        }

        if (datatype) {
          // There are some connection(|).

          if (newdatatype != BRIDGE_DATATYPE_FLAGS &&
              newdatatype != BRIDGE_DATATYPE_POINTINGBUTTON) {
            // Don't connect no-flags. (Example: KeyCode::A | KeyCode::B)
            throw xml_compiler_runtime_error("Cannot connect(|) except ModifierFlag and PointingButton:\n\n" + arg);
          }

          if (newdatatype != datatype) {
            // Don't connect different data type. (Example: PointingButton::A | ModifierFlag::SHIFT_L)
            throw xml_compiler_runtime_error("Cannot connect(|) between different types:\n\n" + arg);
          }
        }

        datatype = newdatatype;
        newvalue |= symbol_map_.get(value);
      }

      remapclasses_initialize_vector_.push_back(datatype);
      ++count;
      remapclasses_initialize_vector_.push_back(newvalue);
      ++count;
    }

    remapclasses_initialize_vector_.update(count_index, count);

    for (const auto& i : filter_vector_.get()) {
      remapclasses_initialize_vector_.push_back(i);
    }
  }
void
xml_compiler::remapclasses_initialize_vector_loader::add_to_initialize_vector(std::string& params,
        uint32_t type) const
{
    // ------------------------------------------------------------
    // for backwards compatibility
    boost::replace_all(params, "SimultaneousKeyPresses::Option::RAW", "Option::SIMULTANEOUSKEYPRESSES_RAW");
    boost::replace_all(params, "KeyCode::VK_CHANGE_INPUTMODE_", "KeyCode::VK_CHANGE_INPUTSOURCE_");
    // aliases
    boost::replace_all(params, "@begin", ",");
    boost::replace_all(params, "@end", ",Option::SEPARATOR,");
    boost::replace_all(params, "__{", ",");
    boost::replace_all(params, "}__", ",Option::SEPARATOR,");

    // ------------------------------------------------------------
    size_t count_index = remapclasses_initialize_vector_.size();
    uint32_t count = 0;

    remapclasses_initialize_vector_.push_back(0); // count

    remapclasses_initialize_vector_.push_back(type);
    ++count;

    size_t value_start_index = remapclasses_initialize_vector_.size();

    pqrs::string::tokenizer tokenizer_comma(params, ',');
    std::string arg;
    std::string value;
    while (tokenizer_comma.split_removing_empty(arg)) {
        unsigned int datatype = 0;

        pqrs::string::tokenizer tokenizer_pipe(arg, '|');
        while (tokenizer_pipe.split_removing_empty(value)) {
            unsigned int newdatatype = xml_compiler_utilities::get_datatype(value);
            if (newdatatype == BRIDGE_DATATYPE_NONE) {
                throw xml_compiler_runtime_error("Unknown symbol:\n\n" + value);
            }

            if (datatype) {
                // There are some connection(|).

                if (newdatatype != BRIDGE_DATATYPE_MODIFIERFLAG) {
                    // Don't connect expect ModifierFlags. (Example: KeyCode::A | KeyCode::B)
                    throw xml_compiler_runtime_error("Cannot connect(|) except ModifierFlag:\n\n" + arg);
                }
            }

            datatype = newdatatype;
            unsigned int newvalue = symbol_map_.get(value);

            remapclasses_initialize_vector_.push_back(datatype);
            ++count;
            remapclasses_initialize_vector_.push_back(newvalue);
            ++count;

            // Unshift Option::USE_SEPARATOR when Option::SEPARATOR is found.
            if (datatype == BRIDGE_DATATYPE_OPTION &&
                    newvalue == symbol_map_cache_option_separator_) {
                remapclasses_initialize_vector_.insert(value_start_index, symbol_map_cache_option_use_separator_);
                ++count;
                remapclasses_initialize_vector_.insert(value_start_index, BRIDGE_DATATYPE_OPTION);
                ++count;
            }
        }

        // Append BRIDGE_DATATYPE_MODIFIERFLAGS_END if needed
        if (datatype == BRIDGE_DATATYPE_MODIFIERFLAG) {
            remapclasses_initialize_vector_.push_back(BRIDGE_DATATYPE_MODIFIERFLAGS_END);
            ++count;
            remapclasses_initialize_vector_.push_back(1);
            ++count;
        }
    }

    remapclasses_initialize_vector_.update(count_index, count);

    for (const auto& i : filter_vector_.get()) {
        remapclasses_initialize_vector_.push_back(i);
    }
}
  void
  xml_compiler::filter_vector::add_(uint32_t filter_type,
                                    const std::string& prefix,
                                    const std::string& string)
  {
    std::string string_no_whitespaces(string);
    pqrs::string::remove_whitespaces(string_no_whitespaces);

    size_t count_index = data_.size();
    uint32_t count = 0;

    data_.push_back(count);

    data_.push_back(filter_type);
    ++count;

    pqrs::string::tokenizer tokenizer_comma(string_no_whitespaces, ',');
    std::string arg;
    while (tokenizer_comma.split_removing_empty(arg)) {
      uint32_t filter_value = 0;

      switch (filter_type) {
        case BRIDGE_FILTERTYPE_MODIFIER_NOT:
        case BRIDGE_FILTERTYPE_MODIFIER_ONLY:
        {
          // support '|' for <modifier_only>.
          // For example: <modifier_only>ModifierFlag::COMMAND_L|ModifierFlag::CONTROL_L, ModifierFlag::COMMAND_L|ModifierFlag::OPTION_L</modifier_only>
          pqrs::string::tokenizer tokenizer_pipe(arg, '|');
          std::string value;
          while (tokenizer_pipe.split_removing_empty(value)) {
            std::string key = prefix + value;
            normalize_identifier_(key);
            filter_value |= symbol_map_.get(key);
          }
          break;
        }

        case BRIDGE_FILTERTYPE_DEVICE_NOT:
        case BRIDGE_FILTERTYPE_DEVICE_ONLY:
        {
          if (boost::starts_with(arg, "DeviceVendor")) {
            fill_omitted_device_specifying(count);
          }
          // pass-through (== no break)
        }

        default:
        {
          std::string key = prefix + arg;
          normalize_identifier_(key);
          filter_value = symbol_map_.get(key);
          break;
        }
      }

      data_.push_back(filter_value);
      ++count;
    }

    // ------------------------------------------------------------
    // Fill DeviceProduct, DeviceLocation if needed.
    if (filter_type == BRIDGE_FILTERTYPE_DEVICE_NOT ||
        filter_type == BRIDGE_FILTERTYPE_DEVICE_ONLY) {
      fill_omitted_device_specifying(count);
    }

    // ------------------------------------------------------------
    if (count == 1) {
      // Rollback if filter is empty.
      data_.resize(count_index);
    } else {
      data_[count_index] = count;
    }
  }