static void gtf_visitor_free(GtNodeVisitor *nv)
{
  GtGTFVisitor *gtf_visitor = gtf_visitor_cast(nv);
  gt_assert(gtf_visitor);
  gt_array_delete(gtf_visitor->exon_features);
  gt_array_delete(gtf_visitor->CDS_features);
}
static int gtf_visitor_comment_node(GtNodeVisitor *nv, GtCommentNode *c,
                                    GT_UNUSED GtError *err)
{
  GtGTFVisitor *gtf_visitor;
  gt_error_check(err);
  gtf_visitor = gtf_visitor_cast(nv);
  gt_file_xprintf(gtf_visitor->outfp, "#%s\n", gt_comment_node_get_comment(c));
  return 0;
}
GtNodeVisitor* gt_gtf_visitor_new(GtFile *outfp)
{
  GtNodeVisitor *nv = gt_node_visitor_create(gt_gtf_visitor_class());
  GtGTFVisitor *gtf_visitor = gtf_visitor_cast(nv);
  gtf_visitor->gene_id = 0;
  gtf_visitor->exon_features = gt_array_new(sizeof (GtGenomeNode*));
  gtf_visitor->CDS_features = gt_array_new(sizeof (GtGenomeNode*));
  gtf_visitor->outfp = outfp;
  return nv;
}
static int gtf_visitor_genome_feature(GtNodeVisitor *gv, GtFeatureNode *gf,
                                      GtError *err)
{
  GtGTFVisitor *gtf_visitor;
  int had_err;
  gt_error_check(err);
  gtf_visitor = gtf_visitor_cast(gv);
  had_err = gt_genome_node_traverse_children((GtGenomeNode*) gf, gtf_visitor,
                                          gtf_show_genome_feature, false, err);
  return had_err;
}
static int gtf_visitor_feature_node(GtNodeVisitor *nv, GtFeatureNode *fn,
                                    GtError *err)
{
  GtGTFVisitor *gtf_visitor;
  int had_err;
  gt_error_check(err);
  gtf_visitor = gtf_visitor_cast(nv);
  had_err = gt_feature_node_traverse_children(fn, gtf_visitor,
                                              gtf_show_feature_node, false,
                                              err);
  return had_err;
}