complete implementation