needs `@SuppressWarnings("unchecked")`