more or less complete implementation