today I have ran into strange javac behavior regarding generic type inference. Here's example class to ilustrate this strange behavior:
import java.util.Map;
import java.util.Collections;
import java.util.HashMap;
public class Test {
    protected <T> T strange(T t, Map<String, String> map) {
        return t;
    }
    protected void ok(Map<String, String> map) {}
    protected <T> T test(T t) {
        T res = strange(t , new HashMap<String, String>());
        //Doesn't work
        //res = strange(t, new <String, String>HashMap());
        ok(new <String, String>HashMap());
        res = strange(t, Collections.<String, String>emptyMap());
        //Doesn't work
        //res = strange(t, Collections.EMPTY_MAP);
        res = strange(t, (Map<String, String>) Collections.EMPTY_MAP);
        ok(Collections.EMPTY_MAP);
        return res;
    }
}
Notice //Doesn't work comments. If you uncomment this code you will get strange compiler error:
Test.java:18: error: incompatible types
        res = strange(t, Collections.EMPTY_MAP);
                     ^
  required: T
  found:    Object
  where T is a type-variable:
    T extends Object declared in method <T>test(T)
Strange thing is that error complains about strange method return type is Object and not T, but when second unsafe parameter is cast to correct type then T is inferred correctly. 
Can someone explain if this is correct behavior? Because it looks strange to me. Can it be a compiler bug?
Why this line works
T res = strange(t , new HashMap<String, String>());
and this one is doesn't?
T res = strange(t, new <String, String>HashMap());
I have tested it with java 7 and 6.
 
     
    