diff --git a/src/test/java/org/eclipse/yasson/documented/DocumentationExampleTest.java b/src/test/java/org/eclipse/yasson/documented/DocumentationExampleTest.java
new file mode 100644
index 0000000..ac4f751
--- /dev/null
+++ b/src/test/java/org/eclipse/yasson/documented/DocumentationExampleTest.java
@@ -0,0 +1,576 @@
+package org.eclipse.yasson.documented;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.lang.reflect.Type;
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.json.bind.Jsonb;
+import javax.json.bind.JsonbBuilder;
+import javax.json.bind.JsonbConfig;
+import javax.json.bind.adapter.JsonbAdapter;
+import javax.json.bind.annotation.JsonbCreator;
+import javax.json.bind.annotation.JsonbDateFormat;
+import javax.json.bind.annotation.JsonbNillable;
+import javax.json.bind.annotation.JsonbNumberFormat;
+import javax.json.bind.annotation.JsonbProperty;
+import javax.json.bind.annotation.JsonbTransient;
+import javax.json.bind.serializer.DeserializationContext;
+import javax.json.bind.serializer.JsonbDeserializer;
+import javax.json.bind.serializer.JsonbSerializer;
+import javax.json.bind.serializer.SerializationContext;
+import javax.json.stream.JsonGenerator;
+import javax.json.stream.JsonParser;
+
+import org.junit.Test;
+
+/**
+ * Contains tests from http://json-b.net/docs/user-guide.html
+ */
+public class DocumentationExampleTest {
+
+    public static class Dog {
+        public String name;
+        public int age;
+        public boolean bitable;
+    }
+
+    @Test
+    public void testMappingExample() {
+        // Create a dog instance
+        Dog dog = new Dog();
+        dog.name = "Falco";
+        dog.age = 4;
+        dog.bitable = false;
+
+        // Create Jsonb and serialize
+        Jsonb jsonb = JsonbBuilder.create();
+        String result = jsonb.toJson(dog);
+        assertEquals("{\"age\":4,\"bitable\":false,\"name\":\"Falco\"}", result);
+
+        // Deserialize back
+        dog = jsonb.fromJson("{\"name\":\"Falco\",\"age\":4,\"bites\":false}", Dog.class);
+        assertEquals("Falco", dog.name);
+        assertEquals(4, dog.age);
+        assertEquals(false, dog.bitable);
+    }
+
+    @Test
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    public void testMappingCollection() {
+        Dog falco = new Dog();
+        falco.name = "Falco";
+        falco.age = 4;
+        Dog cassidy = new Dog();
+        cassidy.name = "Cassidy";
+        cassidy.age = 5;
+
+        // List of dogs
+        List dogs = new ArrayList();
+        dogs.add(falco);
+        dogs.add(cassidy);
+
+        // Create Jsonb and serialize
+        Jsonb jsonb = JsonbBuilder.create();
+        String result = jsonb.toJson(dogs);
+        assertEquals(
+                "[{\"age\":4,\"bitable\":false,\"name\":\"Falco\"},{\"age\":5,\"bitable\":false,\"name\":\"Cassidy\"}]",
+                result);
+
+        // We can also deserialize back into a raw collection, but since there is no way
+        // to infer a type here,
+        // the result will be a list of java.util.Map instances with string keys.
+        dogs = jsonb.fromJson(result, ArrayList.class);
+        assertEquals(2, dogs.size());
+        assertEquals("Falco", ((Map) dogs.get(0)).get("name"));
+        assertEquals("Cassidy", ((Map) dogs.get(1)).get("name"));
+        // assertEquals(4, ((Map) dogs.get(0)).get("age")); // TODO should these
+        // actually be BigDecimals?
+        // assertEquals(5, ((Map) dogs.get(1)).get("age"));
+    }
+
+    @SuppressWarnings("serial")
+    @Test
+    public void testMappingGenericCollection() {
+        Dog falco = new Dog();
+        falco.name = "Falco";
+        falco.age = 4;
+        Dog cassidy = new Dog();
+        cassidy.name = "Cassidy";
+        cassidy.age = 5;
+
+        // List of dogs
+        List<Dog> dogs = new ArrayList<>();
+        dogs.add(falco);
+        dogs.add(cassidy);
+
+        // Create Jsonb and serialize
+        Jsonb jsonb = JsonbBuilder.create();
+        String result = jsonb.toJson(dogs);
+        assertEquals(
+                "[{\"age\":4,\"bitable\":false,\"name\":\"Falco\"},{\"age\":5,\"bitable\":false,\"name\":\"Cassidy\"}]",
+                result);
+
+        // Deserialize back
+        dogs = jsonb.fromJson(result, new ArrayList<Dog>() {
+        }.getClass().getGenericSuperclass());
+        assertEquals(2, dogs.size());
+        assertEquals("Falco", dogs.get(0).name);
+        assertEquals("Cassidy", dogs.get(1).name);
+    }
+
+    @Test
+    public void testFormattedOutput() {
+        Dog pojo = new Dog();
+        pojo.name = "Falco";
+        pojo.age = 4;
+
+        // Create custom configuration with formatted output
+        JsonbConfig config = new JsonbConfig().withFormatting(true);
+
+        // Create Jsonb with custom configuration
+        Jsonb jsonb = JsonbBuilder.create(config);
+
+        // Use it!
+        String result = jsonb.toJson(pojo);
+        assertEquals("\n" + 
+                "{\n" + 
+                "    \"age\": 4,\n" + 
+                "    \"bitable\": false,\n" + 
+                "    \"name\": \"Falco\"\n" + 
+                "}", result);
+    }
+    
+    public static class Person1 {
+        @JsonbProperty("person-name")
+        public String name;
+        public String profession;
+    }
+    
+    @Test
+    public void testChangingPropertyNames1() {
+        Person1 p = new Person1();
+        p.name = "Jason Bourne";
+        p.profession = "Super Agent";
+        Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withFormatting(true));
+        String result = jsonb.toJson(p);
+        assertEquals("\n" +
+                "{\n" + 
+                "    \"person-name\": \"Jason Bourne\",\n" + 
+                "    \"profession\": \"Super Agent\"\n" + 
+                "}", result);
+    }
+    
+    public class Person2 {
+        private String name;
+        private String profession;
+
+        @JsonbProperty("person-name")
+        public String getName() {
+            return name;
+        }
+
+        public String getProfession() {
+            return profession;
+        }
+
+        // public setters ...
+        public void setName(String name) {
+            this.name = name;
+        }
+        public void setProfession(String profession) {
+            this.profession = profession;
+        }
+    }
+    
+    @Test
+    public void testChangingPropertyNames2() {
+        Person2 p = new Person2();
+        p.name = "Jason Bourne";
+        p.profession = "Super Agent";
+        Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withFormatting(true));
+        String result = jsonb.toJson(p);
+        assertEquals("\n" +
+                "{\n" + 
+                "    \"person-name\": \"Jason Bourne\",\n" + 
+                "    \"profession\": \"Super Agent\"\n" + 
+                "}", result);
+    }
+    
+    public static class Person3 {
+        private String name;
+
+        @JsonbProperty("name-to-write")
+        public String getName() {
+            return name;
+        }
+
+        @JsonbProperty("name-to-read")
+        public void setName(String name) {
+            this.name = name;
+        }
+    }
+    
+    @Test
+    public void testChangingPropertyNames3() {
+        Person3 p = new Person3();
+        p.name = "Jason Bourne";
+        Jsonb jsonb = JsonbBuilder.create();
+        String result = jsonb.toJson(p);
+        assertEquals("{\"name-to-write\":\"Jason Bourne\"}", result);
+        
+        String json = "{\"name-to-read\":\"Jason Bourne\"}";
+        Person3 after = jsonb.fromJson(json, Person3.class);
+        assertEquals("Jason Bourne", after.name);
+    }
+    
+    public static class Person4 { // TODO: a non-static class results in an NPE
+        @JsonbTransient
+        private String name;
+
+        private String profession;
+
+        // public getters/setters ...
+        public String getName() {
+            return name;
+        }
+        public void setName(String name) {
+            this.name = name;
+        }
+        public String getProfession() {
+            return this.profession;
+        }
+        public void setProfession(String profession) {
+            this.profession = profession;
+        }
+    }
+    
+    @Test
+    public void testIgnoringProperties() {
+        Person4 p = new Person4();
+        p.name = "Jason Bourne";
+        p.profession = "Super Agent";
+        Jsonb jsonb = JsonbBuilder.create();
+        String result = jsonb.toJson(p);
+        assertEquals("{\"profession\":\"Super Agent\"}", result);
+        
+        String json = "{\"profession\":\"Super Agent\"}";
+        Person4 after = jsonb.fromJson(json, Person4.class);
+        assertEquals("Super Agent", after.profession);
+        assertNull(after.name);
+    }
+    
+    @JsonbNillable
+    public class Person5 {
+        private String name;
+        private String profession;
+
+        // public getters/setters ...
+        public String getName() {
+            return name;
+        }
+        public void setName(String name) {
+            this.name = name;
+        }
+        public String getProfession() {
+            return profession;
+        }
+        public void setProfession(String profession) {
+            this.profession = profession;
+        }
+    }
+    
+    @Test
+    public void testNullHandling1() {
+        Person5 p = new Person5();
+        Jsonb jsonb = JsonbBuilder.create();
+        String result = jsonb.toJson(p);
+        assertEquals("{\"name\":null,\"profession\":null}", result);
+    }
+    
+    public class Person6 {
+        @JsonbProperty(nillable=true)
+        private String name;
+
+        private String profession;
+
+        // public getters/setters ...
+        public String getName() {
+            return name;
+        }
+        public void setName(String name) {
+            this.name = name;
+        }
+        public String getProfession() {
+            return profession;
+        }
+        public void setProfession(String profession) {
+            this.profession = profession;
+        }
+    }
+    
+    @Test
+    public void testNullHandling2() {
+        Person6 p = new Person6();
+        Jsonb jsonb = JsonbBuilder.create();
+        String result = jsonb.toJson(p);
+        assertEquals("{\"name\":null}", result);
+    }
+    
+    public static class Person {
+        public String name;
+        public String profession;
+    }
+
+    @Test
+    public void testNullHandling3() {
+        Person p = new Person();
+        Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withNullValues(true));
+        String result = jsonb.toJson(p);
+        assertEquals("{\"name\":null,\"profession\":null}", result);
+    }
+    
+    public static class Person8 { // TODO: obscure error here if non-static
+        public final String name;
+        public String profession;
+
+        @JsonbCreator
+        public Person8(@JsonbProperty("name") String name) {
+            this.name = name;
+        }
+    }
+    
+    @Test
+    public void testCustomInstantiation() {
+        Jsonb jsonb = JsonbBuilder.create();
+        Person8 p = jsonb.fromJson("{\"name\":\"Jason Bourne\"}", Person8.class);
+        assertEquals("Jason Bourne", p.name);
+    }
+    
+    public static class Person9 {
+        public String name;
+
+        @JsonbDateFormat("dd.MM.yyyy")
+        public LocalDate birthDate;
+
+        @JsonbNumberFormat("#0.00")
+        public BigDecimal salary;
+    }
+    
+    @Test
+    public void testDateNumberFormats1() {
+        Person9 p = new Person9();
+        p.name = "Jason Bourne";
+        p.birthDate = LocalDate.of(1999, 8, 7);
+        p.salary = new BigDecimal("123.45678");
+        Jsonb jsonb = JsonbBuilder.create();
+        String json = jsonb.toJson(p);
+        assertEquals("{\"birthDate\":\"07.08.1999\",\"name\":\"Jason Bourne\",\"salary\":\"123.46\"}", json);
+        
+        Person9 after = jsonb.fromJson("{\"birthDate\":\"07.08.1999\",\"name\":\"Jason Bourne\",\"salary\":\"123.46\"}", Person9.class);
+        assertEquals(p.name, after.name);
+        assertEquals(p.birthDate, after.birthDate);
+        assertEquals(new BigDecimal("123.46"), after.salary);
+    }
+    
+    public static class Person10 {
+        public String name;
+
+        public LocalDate birthDate;
+
+        public BigDecimal salary;
+    }
+    
+    @Test
+    public void testDateNumberFormats2() {
+        Person10 p = new Person10();
+        p.name = "Jason Bourne";
+        p.birthDate = LocalDate.of(1999, 8, 7);
+        p.salary = new BigDecimal("123.45678");
+        Jsonb jsonb = JsonbBuilder.create(new JsonbConfig()//
+                .withDateFormat("dd.MM.yyyy", null)); // TODO: why no withNumberFormat?
+        String json = jsonb.toJson(p);
+        assertEquals("{\"birthDate\":\"07.08.1999\",\"name\":\"Jason Bourne\",\"salary\":123.45678}", json);
+        
+        Person9 after = jsonb.fromJson("{\"birthDate\":\"07.08.1999\",\"name\":\"Jason Bourne\",\"salary\":123.45678}", Person9.class);
+        assertEquals(p.name, after.name);
+        assertEquals(p.birthDate, after.birthDate);
+        assertEquals(p.salary, after.salary);
+    }
+    
+    public static class Customer {
+        private int id;
+        private String name;
+        private String organization;
+        private String position;
+        
+        public int getId() {
+            return id;
+        }
+        public void setId(int id) {
+            this.id = id;
+        }
+        public String getName() {
+            return name;
+        }
+        public void setName(String name) {
+            this.name = name;
+        }
+        public String getOrganization() {
+            return organization;
+        }
+        public void setOrganization(String organization) {
+            this.organization = organization;
+        }
+        public String getPosition() {
+            return position;
+        }
+        public void setPosition(String position) {
+            this.position = position;
+        }
+    }
+
+    public static class CustomerAnnotated {
+        @JsonbProperty("customer_id")
+        private int id;
+
+        @JsonbProperty("customer_name")
+        private String name;
+        
+        public int getId() {
+            return id;
+        }
+        public void setId(int id) {
+            this.id = id;
+        }
+        public String getName() {
+            return name;
+        }
+        public void setName(String name) {
+            this.name = name;
+        }
+    }
+
+    public static class CustomerAdapter implements JsonbAdapter<Customer, CustomerAnnotated> {
+        @Override
+        public CustomerAnnotated adaptToJson(Customer c) throws Exception {
+            CustomerAnnotated customer = new CustomerAnnotated();
+            customer.setId(c.getId());
+            customer.setName(c.getName());
+            return customer;
+        }
+
+        @Override
+        public Customer adaptFromJson(CustomerAnnotated adapted) throws Exception {
+            Customer customer = new Customer();
+            customer.setId(adapted.getId());
+            customer.setName(adapted.getName());
+            return customer;
+        }
+    }
+    
+    @Test
+    public void testAdapters1() {
+        // Create Jsonb with default configuration
+        Jsonb jsonb = JsonbBuilder.create();
+
+        // Create customer
+        Customer customer = new Customer();
+
+        customer.setId(1);
+        customer.setName("Jason Bourne");
+        customer.setOrganization("Super Agents");
+        customer.setPosition("Super Agent");
+
+        // Serialize
+        String json = jsonb.toJson(customer);
+        assertEquals("{\"id\":1,\"name\":\"Jason Bourne\",\"organization\":\"Super Agents\",\"position\":\"Super Agent\"}", json);
+    }
+    
+    @Test
+    public void testAdapters2() {
+     // Create custom configuration
+        JsonbConfig config = new JsonbConfig()
+            .withAdapters(new CustomerAdapter());
+
+        // Create Jsonb with custom configuration
+        Jsonb jsonb = JsonbBuilder.create(config);
+
+        // Create customer
+        Customer customer = new Customer();
+
+        customer.setId(1);
+        customer.setName("Jason Bourne");
+        customer.setOrganization("Super Agents");
+        customer.setPosition("Super Agent");
+
+        // Serialize
+        String json = jsonb.toJson(customer);
+        assertEquals("{\"customer_id\":1,\"customer_name\":\"Jason Bourne\"}", json);
+    }
+    
+    public static class CustomerSerializer implements JsonbSerializer<Customer> {
+        @Override
+        public void serialize(Customer customer, JsonGenerator generator, SerializationContext ctx) {
+            generator.writeStartObject();
+            generator.write("customer_id", customer.getId());
+            generator.write("customer_name", customer.getName());
+            generator.writeEnd();
+        }
+    }
+
+    public static class CustomerDeserializer implements JsonbDeserializer<Customer> {
+        @Override
+        public Customer deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) {
+            Customer customer = new Customer();
+            JsonParser.Event next;
+
+            // Moving parser by hand looking for customer_id and customer_name properties
+            while ((next = parser.next()) != JsonParser.Event.END_OBJECT) {
+                if (next == JsonParser.Event.KEY_NAME) {
+                    String jsonKeyName = parser.getString();
+
+                    // Move to json value
+                    parser.next();
+
+                    if ("customer_id".equals(jsonKeyName)) {
+                        customer.setId(parser.getInt());
+                    } else if ("customer_name".equals(jsonKeyName)) {
+                        customer.setName(parser.getString());
+                    }
+                }
+            }
+            return customer;
+        }
+    }
+    
+    @Test
+    public void testSerializerDeserializer() {
+        // Create pojo
+        Customer customer = new Customer();
+        customer.setId(1);
+        customer.setName("Freddie");
+        customer.setOrganization("Super Agents");
+        customer.setPosition("Super Agent");
+
+        // Also configurable with @JsonbSerializer / JsonbDeserializer on properties and class.
+        JsonbConfig config = new JsonbConfig()
+                .withSerializers(new CustomerSerializer())
+                .withDeserializers(new CustomerDeserializer());
+
+        Jsonb jsonb = JsonbBuilder.create(config);
+        String json = jsonb.toJson(customer);
+        assertEquals("{\"customer_id\":1,\"customer_name\":\"Freddie\"}", json);
+        
+        Customer result = jsonb.fromJson(json, Customer.class);
+        assertEquals(customer.getId(), result.getId());
+        assertEquals(customer.getName(), result.getName());
+        assertNull(result.getOrganization());
+        assertNull(result.getPosition());
+    }
+}
