namespace hfst {

// *** Add default implementation type *** //

hfst::ImplementationType type = hfst::TROPICAL_OPENFST_TYPE;
void set_default_fst_type(hfst::ImplementationType t) { type = t; }
hfst::ImplementationType get_default_fst_type() { return type; }

std::string fst_type_to_string(hfst::ImplementationType t) { std::string retval = hfst::implementation_type_to_string(t); return retval; }

bool is_diacritic(const std::string & symbol) { return hfst::FdOperation::is_diacritic(symbol); }

HfstTransducer * empty_transducer()
{
  hfst::xre::XreCompiler comp(hfst::get_default_fst_type());
  return hfst::hfst_regex(comp, "[0 - 0]", "");
}
HfstTransducer * copy_hfst_transducer(const hfst::HfstTransducer & t) { return new HfstTransducer(t); }
HfstTransducer * copy_hfst_transducer_from_basic_transducer(const hfst::implementations::HfstBasicTransducer & t) { return new HfstTransducer(t, type); }
HfstTransducer * copy_hfst_transducer_from_basic_transducer(const hfst::implementations::HfstBasicTransducer & t, hfst::ImplementationType impl) { return new HfstTransducer(t, impl); }

hfst::HfstOutputStream * create_hfst_output_stream(const std::string & filename, hfst::ImplementationType type, bool hfst_format)
{
        if (filename == "") { return new hfst::HfstOutputStream(type, hfst_format); }
        else { return new hfst::HfstOutputStream(filename, type, hfst_format); }
}

hfst_ol::PmatchContainer * create_pmatch_container(const std::string & filename)
{
    std::ifstream instream(filename.c_str(),
                           std::ifstream::binary);
    if (!instream.good()) {
        return NULL;
    }
    return new hfst_ol::PmatchContainer(instream);
}

}
