import java.util.Collection;
import java.util.Collections;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.checkerframework.checker.nullness.qual.*;
public class MisuseProperties {
void propertiesToHashtable(Properties p) {
//:: error: (argument.type.incompatible)
p.setProperty("line.separator", null);
//:: error: (argument.type.incompatible)
p.put("line.separator", null);
Hashtable h = p;
// Error, because HashTable value has NonNull bound.
//:: error: (argument.type.incompatible) :: warning: [unchecked] unchecked call to put(K,V) as a member of the raw type java.util.Hashtable
h.put("line.separator", null);
//:: error: (argument.type.incompatible)
System.setProperty("line.separator", null);
Dictionary d1 = p;
// No error, because Dictionary value has Nullable bound.
//:: warning: [unchecked] unchecked call to put(K,V) as a member of the raw type java.util.Dictionary
d1.put("line.separator", null);
//:: error: (assignment.type.incompatible)
Dictionary<Object, @Nullable Object> d2 = p;
d2.put("line.separator", null);
System.setProperties(p); // OK; p has no null values
System.clearProperty("foo.bar"); // OK
// Each of the following should cause an error, because it leaves
// line.separator null.
// These first few need to be special-cased, I think:
System.clearProperty("line.separator");
p.remove("line.separator");
p.clear();
// These are OK because they seem to only add, not remove, properties:
// p.load(InputStream), p.load(Reader), p.loadFromXML(InputStream)
// The following problems are a result of treating a Properties as one
// of its supertypes. Here are some solutions:
// * Forbid treating a Properties object as any of its supertypes.
// * Create an annotation on a Properties object, such as
// @HasSystemProperties, and forbid some operations (or any
// treatment as a supertype) for such properties.
Set<@KeyFor("p") Object> keys = p.keySet();
// now remove "line.separator" from the set
keys.remove("line.separator");
keys.removeAll(keys);
keys.clear();
keys.retainAll(Collections.EMPTY_SET);
Set<Map.Entry<@KeyFor("p") Object, Object>> entries = p.entrySet();
// now remove the pair containing "line.separator" from the set, as above
Collection<Object> values = p.values();
// now remove the line separator value from values, as above
Hashtable h9 = p;
h9.remove("line.separator");
h9.clear();
// also access via entrySet, keySet, values
Dictionary d9 = p;
d9.remove("line.separator");
}
}