@@ -0,0 +1,2779 @@
+package com.fasterxml.jackson.databind.jsontype.ext;%0A%0Aimport com.fasterxml.jackson.annotation.*;%0A%0Aimport com.fasterxml.jackson.databind.*;%0Aimport com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver;%0Aimport com.fasterxml.jackson.databind.jsontype.impl.TypeIdResolverBase;%0A%0A// %5Bdatabind#2588%5D / %5Bdatabind#2610%5D%0Apublic class ExternalTypeId2588Test extends BaseMapTest%0A%7B%0A    // %5Bdatabind#2588%5D%0A    interface Animal %7B %7D%0A%0A    static class Cat implements Animal %7B %7D%0A%0A    public static class Dog implements Animal %7B %7D%0A%0A    @JsonIgnoreProperties(ignoreUnknown = true)%0A    static class Pet %7B%0A        final String type;%0A%0A        @JsonTypeInfo(use = JsonTypeInfo.Id.NAME,%0A                include = JsonTypeInfo.As.EXTERNAL_PROPERTY,%0A                property = %22type%22)%0A        @JsonTypeIdResolver(AnimalTypeIdResolver.class)%0A        private final Animal animal;%0A%0A        @JsonCreator%0A        public Pet(@JsonProperty(%22type%22) String type,%0A                   @JsonProperty(%22animal%22) Animal animal) %7B%0A            this.type = type;%0A            this.animal = animal;%0A        %7D%0A    %7D%0A%0A    static class AnimalTypeIdResolver extends TypeIdResolverBase %7B%0A        @Override%0A        public String idFromValue(Object value) %7B%0A            return idFromValueAndType(value, value.getClass());%0A        %7D%0A%0A        @Override%0A        public String idFromValueAndType(Object value, Class%3C?%3E suggestedType) %7B%0A            if (suggestedType.isAssignableFrom(Cat.class)) %7B%0A                return %22cat%22;%0A            %7D else if (suggestedType.isAssignableFrom(Dog.class)) %7B%0A                return %22dog%22;%0A            %7D%0A            return null;%0A        %7D%0A%0A        @Override%0A        public JavaType typeFromId(DatabindContext context, String id) %7B%0A            if (%22cat%22.equals(id)) %7B%0A                return context.constructType(Cat.class);%0A            %7D else if (%22dog%22.equals(id)) %7B%0A                return context.constructType(Dog.class);%0A            %7D%0A            return null;%0A        %7D%0A%0A        @Override%0A        public JsonTypeInfo.Id getMechanism() %7B%0A            return JsonTypeInfo.Id.NAME;%0A        %7D%0A    %7D%0A%0A    // %5Bdatabind#2588%5D%0A    public void testExternalTypeId2588() throws Exception%0A    %7B%0A        final ObjectMapper mapper = newJsonMapper();%0A        Pet pet;%0A%0A        // works?%0A        %0A        pet = mapper.readValue(aposToQuotes(%0A%22%7B%5Cn%22 + %0A%22  'type': 'cat',%5Cn%22 + %0A%22  'animal': %7B %7D,%5Cn%22 + %0A%22  'ignoredObject%5C%22: %7B%5Cn%22 + %0A%22    'someField': 'someValue'%5Cn%22 + %0A%22  %7D%22+%0A%22%7D%22%0A                ), Pet.class);%0A        assertNotNull(pet);%0A        %0A        // fails:%0A        pet = mapper.readValue(aposToQuotes(%0A%22%7B%5Cn%22 + %0A%22  'animal%5C%22: %7B %7D,%5Cn%22 + %0A%22  'ignoredObject': %7B%5Cn%22 + %0A%22    'someField': 'someValue'%5Cn%22 + %0A%22  %7D,%5Cn%22 + %0A%22  'type': 'cat'%5Cn%22 + %0A%22%7D%22%0A                ), Pet.class);%0A        assertNotNull(pet);%0A    %7D%0A%7D%0A

Add passing test for #2588