Options implements Iterable<Option<T>> { public static Options<String> from(final Map<String, String> stringProperties) { Options<String> options = new Options<>(); stringProperties.forEach( (key, value) -> options.add(new Option<>(key, StringOptionParser::new).update(value)) ); return options; }  Optional<R> ifPresent(final String name, final Function<Option<T>, Optional<R>> function); Optional<T> valueIfPresent(final String name); Option<T> get(final String name); Option<T> get(final Option<T> option); Options<T> add(final Option<T> option); Option<T> add(final String name, final Function<Option<T>, OptionParser<T>> parser); Option<T> add(final org.icij.task.annotation.Option option, final Function<Option<T>, OptionParser<T>>
            parser); void add(final org.icij.task.annotation.OptionsClass optionsClass, final Function<Option<T>, OptionParser<T>>
            parser); static Options<String> from(final Map<String, String> stringProperties); static Options<String> from(final Properties stringProperties); @Override Iterator<Option<T>> iterator(); @Override String toString(); @Override boolean equals(Object o); @Override int hashCode(); Options<T> createFrom(final Options<T> optionsToBind);  }
@Test public void test_options_equals() { HashMap<String, String> stringProperties = new HashMap<String, String>() {{ put("key1", "value1"); put("key2", "value2"); }}; assertEquals(Options.from(stringProperties), Options.from(stringProperties)); }