initial version extracted from another project, still needs a lot of housekeeping