http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/access/loader/mapper/DefaultJdbc2JavaTypeMapper.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/loader/mapper/DefaultJdbc2JavaTypeMapper.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/access/loader/mapper/DefaultJdbc2JavaTypeMapper.java
deleted file mode 100644
index de9e02d..0000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/access/loader/mapper/DefaultJdbc2JavaTypeMapper.java
+++ /dev/null
@@ -1,282 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-package org.apache.cayenne.access.loader.mapper;
-
-import org.apache.cayenne.dba.TypesMapping;
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.util.Util;
-
-import java.io.Serializable;
-import java.math.BigInteger;
-import java.sql.Types;
-import java.util.Calendar;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-/**
- * @since 4.0.
- */
-public class DefaultJdbc2JavaTypeMapper implements Jdbc2JavaTypeMapper {
-
-       // Never use "-1" or any other normal integer, since there
-       // is a big chance it is being reserved in java.sql.Types
-       public static final int NOT_DEFINED = Integer.MAX_VALUE;
-
-       // char constants for Java data types
-       public static final String JAVA_LONG = "java.lang.Long";
-       public static final String JAVA_BYTES = "byte[]";
-       public static final String JAVA_BOOLEAN = "java.lang.Boolean";
-       public static final String JAVA_STRING = "java.lang.String";
-       public static final String JAVA_SQLDATE = "java.sql.Date";
-       public static final String JAVA_UTILDATE = "java.util.Date";
-       public static final String JAVA_BIGDECIMAL = "java.math.BigDecimal";
-       public static final String JAVA_DOUBLE = "java.lang.Double";
-       public static final String JAVA_FLOAT = "java.lang.Float";
-       public static final String JAVA_INTEGER = "java.lang.Integer";
-       public static final String JAVA_SHORT = "java.lang.Short";
-       public static final String JAVA_BYTE = "java.lang.Byte";
-       public static final String JAVA_TIME = "java.sql.Time";
-       public static final String JAVA_TIMESTAMP = "java.sql.Timestamp";
-       public static final String JAVA_BLOB = "java.sql.Blob";
-
-       /**
-        * Keys: java class names, Values: SQL int type definitions from
-        * java.sql.Types
-        */
-       private final Map<String, Integer> javaSqlEnum = new HashMap<>();
-
-       private final Map<DbType, String> mapping = new HashMap<>();
-       private final SortedSet<DbType> dbTypes = new TreeSet<>();
-
-       private Map<String, String> classToPrimitive;
-
-       {
-               add(Types.BIGINT, JAVA_LONG);
-               add(Types.BINARY, JAVA_BYTES);
-               add(Types.BIT, JAVA_BOOLEAN);
-               add(Types.BOOLEAN, JAVA_BOOLEAN);
-               add(Types.BLOB, JAVA_BYTES);
-               add(Types.CLOB, JAVA_STRING);
-               add(Types.NCLOB, JAVA_STRING);
-               add(Types.SQLXML, JAVA_STRING);
-               add(Types.CHAR, JAVA_STRING);
-               add(Types.NCHAR, JAVA_STRING);
-               add(Types.DATE, JAVA_UTILDATE);
-               add(Types.DECIMAL, JAVA_BIGDECIMAL);
-               add(Types.DOUBLE, JAVA_DOUBLE);
-               add(Types.FLOAT, JAVA_FLOAT);
-               add(Types.INTEGER, JAVA_INTEGER);
-               add(Types.LONGVARCHAR, JAVA_STRING);
-               add(Types.LONGNVARCHAR, JAVA_STRING);
-               add(Types.LONGVARBINARY, JAVA_BYTES);
-               add(Types.NUMERIC, JAVA_BIGDECIMAL);
-               add(Types.REAL, JAVA_FLOAT);
-               add(Types.SMALLINT, JAVA_SHORT);
-               add(Types.TINYINT, JAVA_SHORT);
-               add(Types.TIME, JAVA_UTILDATE);
-               add(Types.TIMESTAMP, JAVA_UTILDATE);
-               add(Types.VARBINARY, JAVA_BYTES);
-               add(Types.VARCHAR, JAVA_STRING);
-               add(Types.NVARCHAR, JAVA_STRING);
-
-               javaSqlEnum.put(JAVA_LONG, Types.BIGINT);
-               javaSqlEnum.put(JAVA_BYTES, Types.BINARY);
-               javaSqlEnum.put(JAVA_BOOLEAN, Types.BIT);
-               javaSqlEnum.put(JAVA_STRING, Types.VARCHAR);
-               javaSqlEnum.put(JAVA_SQLDATE, Types.DATE);
-               javaSqlEnum.put(JAVA_UTILDATE, Types.DATE);
-               javaSqlEnum.put(JAVA_TIMESTAMP, Types.TIMESTAMP);
-               javaSqlEnum.put(JAVA_BIGDECIMAL, Types.DECIMAL);
-               javaSqlEnum.put(JAVA_DOUBLE, Types.DOUBLE);
-               javaSqlEnum.put(JAVA_FLOAT, Types.FLOAT);
-               javaSqlEnum.put(JAVA_INTEGER, Types.INTEGER);
-               javaSqlEnum.put(JAVA_SHORT, Types.SMALLINT);
-               javaSqlEnum.put(JAVA_BYTE, Types.SMALLINT);
-               javaSqlEnum.put(JAVA_TIME, Types.TIME);
-               javaSqlEnum.put(JAVA_TIMESTAMP, Types.TIMESTAMP);
-
-               // add primitives
-               javaSqlEnum.put("byte", Types.TINYINT);
-               javaSqlEnum.put("int", Types.INTEGER);
-               javaSqlEnum.put("short", Types.SMALLINT);
-               javaSqlEnum.put("char", Types.CHAR);
-               javaSqlEnum.put("double", Types.DOUBLE);
-               javaSqlEnum.put("long", Types.BIGINT);
-               javaSqlEnum.put("float", Types.FLOAT);
-               javaSqlEnum.put("boolean", Types.BIT);
-
-               classToPrimitive = new HashMap<>();
-               classToPrimitive.put(Byte.class.getName(), "byte");
-               classToPrimitive.put(Long.class.getName(), "long");
-               classToPrimitive.put(Double.class.getName(), "double");
-               classToPrimitive.put(Boolean.class.getName(), "boolean");
-               classToPrimitive.put(Float.class.getName(), "float");
-               classToPrimitive.put(Short.class.getName(), "short");
-               classToPrimitive.put(Integer.class.getName(), "int");
-       }
-
-       private Boolean usePrimitives;
-
-       /**
-        * Returns default java.sql.Types type by the Java type name.
-        *
-        * @param className
-        *            Fully qualified Java Class name.
-        * @return The SQL type or NOT_DEFINED if no type found.
-        */
-       public int getJdbcTypeByJava(DbAttribute attribute, String className) {
-               if (className == null) {
-                       return NOT_DEFINED;
-               }
-
-               Integer type = javaSqlEnum.get(className);
-               if (type != null) {
-                       return type;
-               }
-
-               // try to load a Java class - some nonstandard mappings may work
-               try {
-                       return getSqlTypeByJava(attribute, 
Util.getJavaClass(className));
-               } catch (Throwable th) {
-                       return NOT_DEFINED;
-               }
-       }
-
-       public void add(int jdbcType, String java) {
-               add(new DbType(TypesMapping.getSqlNameByType(jdbcType)), java);
-       }
-
-       @Override
-       public void add(DbType type, String java) {
-               mapping.put(type, java);
-               dbTypes.add(type);
-       }
-
-       /**
-        * Guesses a default JDBC type for the Java class.
-        *
-        * @since 1.1
-        */
-       protected int getSqlTypeByJava(DbAttribute attribute, Class<?> 
javaClass) {
-               if (javaClass == null) {
-                       return NOT_DEFINED;
-               }
-
-               // check standard mapping of class and superclasses
-               Class<?> aClass = javaClass;
-               while (aClass != null) {
-
-                       String name;
-
-                       if (aClass.isArray()) {
-                               name = aClass.getComponentType().getName() + 
"[]";
-                       } else {
-                               name = aClass.getName();
-                       }
-
-                       Object type = javaSqlEnum.get(name);
-                       if (type != null) {
-                               return ((Number) type).intValue();
-                       }
-
-                       aClass = aClass.getSuperclass();
-               }
-
-               // check non-standard JDBC types that are still supported by JPA
-               if (javaClass.isArray()) {
-
-                       Class<?> elementType = javaClass.getComponentType();
-                       if (Character.class.isAssignableFrom(elementType) || 
Character.TYPE.isAssignableFrom(elementType)) {
-                               return Types.VARCHAR;
-                       } else if (Byte.class.isAssignableFrom(elementType) || 
Byte.TYPE.isAssignableFrom(elementType)) {
-                               return Types.VARBINARY;
-                       }
-               }
-
-               if (Calendar.class.isAssignableFrom(javaClass)) {
-                       return Types.TIMESTAMP;
-               }
-
-               if (BigInteger.class.isAssignableFrom(javaClass)) {
-                       return Types.BIGINT;
-               }
-
-               if (Serializable.class.isAssignableFrom(javaClass)) {
-                       // serializable check should be the last one when all 
other mapping
-                       // attempts failed
-                       return Types.VARBINARY;
-               }
-
-               return NOT_DEFINED;
-       }
-
-       /**
-        * Get the corresponding Java type by its java.sql.Types counterpart. 
Note
-        * that this method should be used as a last resort, with explicit 
mapping
-        * provided by user used as a first choice, as it can only guess how to 
map
-        * certain types, such as NUMERIC, etc.
-        *
-        * @return Fully qualified Java type name or null if not found.
-        */
-       @Override
-       public String getJavaByJdbcType(DbAttribute attribute, int type) {
-               String jdbcType = TypesMapping.getSqlNameByType(type);
-               DbType dbType;
-               if (attribute != null) {
-                       dbType = new DbType(jdbcType, attribute.getMaxLength(), 
attribute.getAttributePrecision(),
-                                       attribute.getScale(), 
attribute.isMandatory());
-               } else {
-                       dbType = new DbType(jdbcType);
-               }
-
-               String typeName = getJavaByJdbcType(dbType);
-
-               if (usePrimitives != null && usePrimitives) {
-                       String primitive = classToPrimitive.get(typeName);
-                       if (primitive != null) {
-                               return primitive;
-                       }
-               }
-
-               return typeName;
-       }
-
-       public String getJavaByJdbcType(DbType type) {
-               for (DbType t : dbTypes) {
-                       if (t.isCover(type)) {
-                               // because dbTypes sorted by specificity we 
will take first and
-                               // the most specific matching
-                               // that applicable for attribute
-                               return mapping.get(t);
-                       }
-               }
-
-               return null;
-       }
-
-       public Boolean getUsePrimitives() {
-               return usePrimitives;
-       }
-
-       public void setUsePrimitives(Boolean usePrimitives) {
-               this.usePrimitives = usePrimitives;
-       }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/access/loader/mapper/Jdbc2JavaTypeMapper.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/loader/mapper/Jdbc2JavaTypeMapper.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/access/loader/mapper/Jdbc2JavaTypeMapper.java
deleted file mode 100644
index 160dc4e..0000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/access/loader/mapper/Jdbc2JavaTypeMapper.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-package org.apache.cayenne.access.loader.mapper;
-
-import org.apache.cayenne.map.DbAttribute;
-
-/**
- * @since 4.0.
- */
-public interface Jdbc2JavaTypeMapper {
-
-    String getJavaByJdbcType(DbAttribute attribute, int type);
-
-    int getJdbcTypeByJava(DbAttribute attribute, String className);
-
-    void add(DbType type, String java);
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/AutoAdapter.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/AutoAdapter.java 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/AutoAdapter.java
index a8876f6..cb436e6 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/AutoAdapter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/AutoAdapter.java
@@ -33,7 +33,6 @@ import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.DbRelationship;
 import org.apache.cayenne.map.EntityResolver;
-import org.apache.cayenne.merge.MergerFactory;
 import org.apache.cayenne.query.Query;
 import org.apache.cayenne.query.SQLAction;
 import org.apache.cayenne.query.SelectQuery;
@@ -216,11 +215,6 @@ public class AutoAdapter implements DbAdapter {
        }
 
        @Override
-       public MergerFactory mergerFactory() {
-               return getAdapter().mergerFactory();
-       }
-
-       @Override
        public void createTableAppendColumn(StringBuffer sqlBuffer, DbAttribute 
column) {
                getAdapter().createTableAppendColumn(sqlBuffer, column);
        }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java
index d72bc31..e89ae4b 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java
@@ -29,7 +29,6 @@ import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.DbRelationship;
 import org.apache.cayenne.map.EntityResolver;
-import org.apache.cayenne.merge.MergerFactory;
 import org.apache.cayenne.query.Query;
 import org.apache.cayenne.query.SQLAction;
 import org.apache.cayenne.query.SelectQuery;
@@ -183,11 +182,6 @@ public interface DbAdapter {
        String tableTypeForView();
 
        /**
-        * @since 3.0
-        */
-       MergerFactory mergerFactory();
-
-       /**
         * Append the column type part of a "create table" to the given
         * {@link StringBuffer}
         *

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java
index 57d3430..979b425 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java
@@ -36,8 +36,11 @@ import org.apache.cayenne.configuration.Constants;
 import org.apache.cayenne.configuration.RuntimeProperties;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.log.JdbcEventLogger;
-import org.apache.cayenne.map.*;
-import org.apache.cayenne.merge.MergerFactory;
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.DbJoin;
+import org.apache.cayenne.map.DbRelationship;
+import org.apache.cayenne.map.EntityResolver;
 import org.apache.cayenne.query.Query;
 import org.apache.cayenne.query.SQLAction;
 import org.apache.cayenne.query.SelectQuery;
@@ -600,13 +603,6 @@ public class JdbcAdapter implements DbAdapter {
        }
 
        /**
-        * @since 3.0
-        */
-       public MergerFactory mergerFactory() {
-               return new MergerFactory();
-       }
-
-       /**
         * @return
         * @since 4.0
         */

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/PerAdapterProvider.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/PerAdapterProvider.java 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/PerAdapterProvider.java
new file mode 100644
index 0000000..d4b2816
--- /dev/null
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/PerAdapterProvider.java
@@ -0,0 +1,46 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.dba;
+
+import org.apache.cayenne.di.DIRuntimeException;
+
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * An injectable provider that returns a given service in a context of a 
specific {@link DbAdapter}.
+ * This allows modules to create adapter-specific extensions without altering 
DbAdapter API.
+ *
+ * @since 4.0
+ */
+public class PerAdapterProvider<T> {
+
+    private Map<String, T> perAdapterValues;
+    private T defaultValue;
+
+    public PerAdapterProvider(Map<String, T> perAdapterValues, T defaultValue) 
{
+        this.perAdapterValues = Objects.requireNonNull(perAdapterValues);
+        this.defaultValue = Objects.requireNonNull(defaultValue);
+    }
+
+    public T get(DbAdapter adapter) throws DIRuntimeException {
+        T t = perAdapterValues.get(adapter.unwrap().getClass().getName());
+        return t != null ? t : defaultValue;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2Adapter.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2Adapter.java 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2Adapter.java
index f71f655..edf8901 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2Adapter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2Adapter.java
@@ -24,7 +24,12 @@ import org.apache.cayenne.access.DataNode;
 import org.apache.cayenne.access.translator.ParameterBinding;
 import org.apache.cayenne.access.translator.select.QualifierTranslator;
 import org.apache.cayenne.access.translator.select.QueryAssembler;
-import org.apache.cayenne.access.types.*;
+import org.apache.cayenne.access.types.BooleanType;
+import org.apache.cayenne.access.types.ByteArrayType;
+import org.apache.cayenne.access.types.CharType;
+import org.apache.cayenne.access.types.ExtendedType;
+import org.apache.cayenne.access.types.ExtendedTypeFactory;
+import org.apache.cayenne.access.types.ExtendedTypeMap;
 import org.apache.cayenne.configuration.Constants;
 import org.apache.cayenne.configuration.RuntimeProperties;
 import org.apache.cayenne.dba.JdbcAdapter;
@@ -34,7 +39,6 @@ import org.apache.cayenne.dba.TypesMapping;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.merge.MergerFactory;
 import org.apache.cayenne.query.Query;
 import org.apache.cayenne.query.SQLAction;
 import org.apache.cayenne.resource.ResourceLocator;
@@ -223,11 +227,6 @@ public class DB2Adapter extends JdbcAdapter {
     }
 
     @Override
-    public MergerFactory mergerFactory() {
-        return new DB2MergerFactory();
-    }
-
-    @Override
     public void bindParameter(
             PreparedStatement statement, ParameterBinding binding) throws 
SQLException, Exception {
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2MergerFactory.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2MergerFactory.java 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2MergerFactory.java
deleted file mode 100644
index 8ae070d..0000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2MergerFactory.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-package org.apache.cayenne.dba.db2;
-
-import org.apache.cayenne.dba.QuotingStrategy;
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.merge.MergerFactory;
-import org.apache.cayenne.merge.MergerToken;
-import org.apache.cayenne.merge.SetColumnTypeToDb;
-
-
-public class DB2MergerFactory extends MergerFactory {
-
-    @Override
-    public MergerToken createSetColumnTypeToDb(
-            final DbEntity entity,
-            DbAttribute columnOriginal,
-            final DbAttribute columnNew) {
-
-        return new SetColumnTypeToDb(entity, columnOriginal, columnNew) {
-
-            @Override
-            protected void appendPrefix(StringBuffer sqlBuffer, 
QuotingStrategy context) {
-                sqlBuffer.append("ALTER TABLE ");
-                sqlBuffer.append(context.quotedFullyQualifiedName(entity));
-                sqlBuffer.append(" ALTER COLUMN ");
-                sqlBuffer.append(context.quotedName(columnNew));
-                sqlBuffer.append(" SET DATA TYPE ");
-            }
-        };
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyAdapter.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyAdapter.java 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyAdapter.java
index 8a3b462..916eb9e 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyAdapter.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyAdapter.java
@@ -25,7 +25,12 @@ import 
org.apache.cayenne.access.translator.ejbql.EJBQLTranslatorFactory;
 import org.apache.cayenne.access.translator.ejbql.JdbcEJBQLTranslatorFactory;
 import org.apache.cayenne.access.translator.select.QualifierTranslator;
 import org.apache.cayenne.access.translator.select.QueryAssembler;
-import org.apache.cayenne.access.types.*;
+import org.apache.cayenne.access.types.ByteType;
+import org.apache.cayenne.access.types.CharType;
+import org.apache.cayenne.access.types.ExtendedType;
+import org.apache.cayenne.access.types.ExtendedTypeFactory;
+import org.apache.cayenne.access.types.ExtendedTypeMap;
+import org.apache.cayenne.access.types.ShortType;
 import org.apache.cayenne.configuration.Constants;
 import org.apache.cayenne.configuration.RuntimeProperties;
 import org.apache.cayenne.dba.JdbcAdapter;
@@ -33,7 +38,6 @@ import org.apache.cayenne.dba.PkGenerator;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.merge.MergerFactory;
 import org.apache.cayenne.resource.ResourceLocator;
 
 import java.sql.PreparedStatement;
@@ -44,14 +48,14 @@ import java.util.List;
 /**
  * DbAdapter implementation for the <a href="http://db.apache.org/derby/";> 
Derby RDBMS
  * </a>. Sample connection settings to use with Derby are shown below. 
<h3>Embedded</h3>
- * 
+ * <p>
  * <pre>
  *  test-derby.jdbc.url = jdbc:derby:testdb;create=true
  *  test-derby.jdbc.driver = org.apache.derby.jdbc.EmbeddedDriver
  * </pre>
- * 
+ * <p>
  * <h3>Network Server</h3>
- * 
+ * <p>
  * <pre>
  *  derbynet.jdbc.url = jdbc:derby://localhost/cayenne
  *  derbynet.jdbc.driver = org.apache.derby.jdbc.ClientDriver
@@ -103,7 +107,7 @@ public class DerbyAdapter extends JdbcAdapter {
     /**
      * Appends SQL for column creation to CREATE TABLE buffer. Only change for 
Derby is
      * that " NULL" is not supported.
-     * 
+     *
      * @since 1.2
      */
     @Override
@@ -118,7 +122,6 @@ public class DerbyAdapter extends JdbcAdapter {
         }
 
 
-
         sqlBuffer.append(quotingStrategy.quotedName(column));
         sqlBuffer.append(' ');
 
@@ -168,7 +171,7 @@ public class DerbyAdapter extends JdbcAdapter {
         translator.setCaseInsensitive(caseInsensitiveCollations);
         return translator;
     }
-    
+
     /**
      * @since 3.1
      */
@@ -180,11 +183,6 @@ public class DerbyAdapter extends JdbcAdapter {
     }
 
     @Override
-    public MergerFactory mergerFactory() {
-        return new DerbyMergerFactory();
-    }
-
-    @Override
     public void bindParameter(
             PreparedStatement statement,
             ParameterBinding binding) throws SQLException, Exception {
@@ -199,10 +197,14 @@ public class DerbyAdapter extends JdbcAdapter {
 
     private int convertNTypes(int sqlType) {
         switch (sqlType) {
-            case Types.NCHAR: return Types.CHAR;
-            case Types.NVARCHAR: return Types.VARCHAR;
-            case Types.LONGNVARCHAR: return Types.LONGVARCHAR;
-            case Types.NCLOB: return Types.CLOB;
+            case Types.NCHAR:
+                return Types.CHAR;
+            case Types.NVARCHAR:
+                return Types.VARCHAR;
+            case Types.LONGNVARCHAR:
+                return Types.LONGVARCHAR;
+            case Types.NCLOB:
+                return Types.CLOB;
 
             default:
                 return sqlType;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyMergerFactory.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyMergerFactory.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyMergerFactory.java
deleted file mode 100644
index 7ce30d4..0000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyMergerFactory.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-package org.apache.cayenne.dba.derby;
-
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.cayenne.dba.DbAdapter;
-import org.apache.cayenne.dba.QuotingStrategy;
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.merge.MergerFactory;
-import org.apache.cayenne.merge.MergerToken;
-import org.apache.cayenne.merge.SetAllowNullToDb;
-import org.apache.cayenne.merge.SetColumnTypeToDb;
-import org.apache.cayenne.merge.SetNotNullToDb;
-
-public class DerbyMergerFactory extends MergerFactory {
-
-    @Override
-    public MergerToken createSetColumnTypeToDb(
-            final DbEntity entity,
-            DbAttribute columnOriginal,
-            final DbAttribute columnNew) {
-
-        return new SetColumnTypeToDb(entity, columnOriginal, columnNew) {
-
-            @Override
-            protected void appendPrefix(StringBuffer sqlBuffer, 
QuotingStrategy context) {
-                // http://db.apache.org/derby/manuals/reference/sqlj26.html
-                sqlBuffer.append("ALTER TABLE ");
-                sqlBuffer.append(context.quotedFullyQualifiedName(entity));
-                sqlBuffer.append(" ALTER ");
-                sqlBuffer.append(context.quotedName(columnNew));
-                sqlBuffer.append(" SET DATA TYPE ");
-            }
-        };
-    }
-
-    @Override
-    public MergerToken createSetNotNullToDb(DbEntity entity, DbAttribute 
column) {
-        return new SetNotNullToDb(entity, column) {
-
-            @Override
-            public List<String> createSql(DbAdapter adapter) {
-                QuotingStrategy context = adapter.getQuotingStrategy();
-
-                return Collections.singletonList("ALTER TABLE " + 
context.quotedFullyQualifiedName(getEntity())
-                        + " ALTER COLUMN " + context.quotedName(getColumn()) + 
" NOT NULL");
-            }
-
-        };
-    }
-
-    @Override
-    public MergerToken createSetAllowNullToDb(DbEntity entity, DbAttribute 
column) {
-        return new SetAllowNullToDb(entity, column) {
-
-            @Override
-            public List<String> createSql(DbAdapter adapter) {
-                QuotingStrategy context = adapter.getQuotingStrategy();
-
-                return Collections.singletonList("ALTER TABLE " + 
context.quotedFullyQualifiedName(getEntity())
-                        + " ALTER COLUMN " + context.quotedName(getColumn()) + 
" NULL");
-            }
-
-        };
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdAdapter.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdAdapter.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdAdapter.java
index 9146bd5..c88c88f 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdAdapter.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdAdapter.java
@@ -76,11 +76,7 @@ public class FirebirdAdapter extends JdbcAdapter {
         map.registerType(new CharType(true, false));
         
     }
-    
-    public FirebirdMergerFactory mergerFactory() {
-        return new FirebirdMergerFactory();
-    }
-    
+
     public void createTableAppendColumn(StringBuffer sqlBuffer, DbAttribute 
column) {
 
         String[] types = externalTypesForJdbcType(column.getType());

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdMergerFactory.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdMergerFactory.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdMergerFactory.java
deleted file mode 100644
index 45f3832..0000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdMergerFactory.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
- 
-package org.apache.cayenne.dba.firebird;
-
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.cayenne.dba.DbAdapter;
-import org.apache.cayenne.dba.QuotingStrategy;
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.merge.MergerFactory;
-import org.apache.cayenne.merge.MergerToken;
-import org.apache.cayenne.merge.AddColumnToDb;
-import org.apache.cayenne.merge.DropColumnToDb;
-import org.apache.cayenne.merge.SetNotNullToDb;
-import org.apache.cayenne.merge.SetAllowNullToDb;
-
-public class FirebirdMergerFactory extends MergerFactory {
-    
-    public MergerToken createDropColumnToDb(DbEntity entity, DbAttribute 
column) {
-        return new DropColumnToDb(entity, column) {
-            public List<String> createSql(DbAdapter adapter) {
-                QuotingStrategy quoting = adapter.getQuotingStrategy();
-                return Collections.singletonList("ALTER TABLE " + 
quoting.quotedFullyQualifiedName(getEntity())
-                        + " DROP " + quoting.quotedName(getColumn()));
-            }
-        };
-    }
-    
-    @Override
-    public MergerToken createSetNotNullToDb(DbEntity entity, DbAttribute 
column) {
-        return new SetNotNullToDb(entity, column) {
-            public List<String> createSql(DbAdapter adapter) {
-                QuotingStrategy context = adapter.getQuotingStrategy();
-                String entityName = 
context.quotedFullyQualifiedName(getEntity()) ;
-                String columnName = context.quotedName(getColumn());
-                // Firebird doesn't support ALTER TABLE table_name ALTER 
column_name SET NOT NULL
-                // but this might be achived by modyfication of system tables 
-                return Collections.singletonList(String.format("UPDATE 
RDB$RELATION_FIELDS SET RDB$NULL_FLAG = 1 "+ 
-                "WHERE RDB$FIELD_NAME = '%s' AND RDB$RELATION_NAME = '%s'", 
columnName, entityName));
-            }
-        };
-    }
-    
-    @Override
-    public MergerToken createSetAllowNullToDb(DbEntity entity, DbAttribute 
column) {
-        return new SetAllowNullToDb(entity, column) {
-            public List<String> createSql(DbAdapter adapter) {
-                QuotingStrategy context = adapter.getQuotingStrategy();
-                String entityName = 
context.quotedFullyQualifiedName(getEntity()) ;
-                String columnName = context.quotedName(getColumn()); 
-                // Firebird doesn't support ALTER TABLE table_name ALTER 
column_name DROP NOT NULL
-                // but this might be achived by modyfication system tables 
-                return Collections.singletonList(String.format("UPDATE 
RDB$RELATION_FIELDS SET RDB$NULL_FLAG = NULL "+
-                " WHERE RDB$FIELD_NAME = '%s' AND RDB$RELATION_NAME = '%s'", 
columnName, entityName));
-            }
-        };
-    }
-    
-    
-    public MergerToken createAddColumnToDb(DbEntity entity, DbAttribute 
column) {
-        return new AddColumnToDb(entity, column) {
-            protected void appendPrefix(StringBuffer sqlBuffer, 
QuotingStrategy context) {
-                sqlBuffer.append("ALTER TABLE ");
-                
sqlBuffer.append(context.quotedFullyQualifiedName(getEntity()));
-                sqlBuffer.append(" ADD ");
-                sqlBuffer.append(context.quotedName(getColumn()));
-                sqlBuffer.append(" ");
-            }
-        };
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2Adapter.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2Adapter.java 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2Adapter.java
index 768d466..0d99869 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2Adapter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2Adapter.java
@@ -27,7 +27,6 @@ import org.apache.cayenne.dba.JdbcAdapter;
 import org.apache.cayenne.dba.PkGenerator;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.merge.MergerFactory;
 import org.apache.cayenne.resource.ResourceLocator;
 
 import java.util.List;
@@ -57,11 +56,6 @@ public class H2Adapter extends JdbcAdapter {
     }
 
     @Override
-    public MergerFactory mergerFactory() {
-        return new H2MergerFactory();
-    }
-
-    @Override
     public void createTableAppendColumn(StringBuffer sqlBuffer, DbAttribute 
column) {
         super.createTableAppendColumn(sqlBuffer, column);
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2MergerFactory.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2MergerFactory.java 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2MergerFactory.java
deleted file mode 100644
index 6ec19aa..0000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2MergerFactory.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.dba.h2;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.cayenne.dba.DbAdapter;
-import org.apache.cayenne.dba.QuotingStrategy;
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.merge.MergerFactory;
-import org.apache.cayenne.merge.MergerToken;
-import org.apache.cayenne.merge.SetAllowNullToDb;
-import org.apache.cayenne.merge.SetColumnTypeToDb;
-import org.apache.cayenne.merge.SetPrimaryKeyToDb;
-
-/**
- * @since 3.0
- */
-public class H2MergerFactory extends MergerFactory {
-
-    @Override
-    public MergerToken createSetColumnTypeToDb(final DbEntity entity, 
DbAttribute columnOriginal,
-            final DbAttribute columnNew) {
-        return new SetColumnTypeToDb(entity, columnOriginal, columnNew) {
-
-            @Override
-            protected void appendPrefix(StringBuffer sqlBuffer, 
QuotingStrategy context) {
-                sqlBuffer.append("ALTER TABLE ");
-                sqlBuffer.append(context.quotedFullyQualifiedName(entity));
-                sqlBuffer.append(" ALTER ");
-                sqlBuffer.append(context.quotedName(columnNew));
-                sqlBuffer.append(" ");
-            }
-        };
-    }
-
-    @Override
-    public MergerToken createSetAllowNullToDb(DbEntity entity, DbAttribute 
column) {
-        return new SetAllowNullToDb(entity, column) {
-
-            @Override
-            public List<String> createSql(DbAdapter adapter) {
-                return Collections.singletonList("ALTER TABLE " + 
getEntity().getFullyQualifiedName()
-                        + " ALTER COLUMN " + getColumn().getName() + " SET 
NULL");
-            }
-
-        };
-    }
-
-    @Override
-    public MergerToken createSetPrimaryKeyToDb(DbEntity entity, 
Collection<DbAttribute> primaryKeyOriginal,
-            Collection<DbAttribute> primaryKeyNew, String 
detectedPrimaryKeyName) {
-        return new SetPrimaryKeyToDb(entity, primaryKeyOriginal, 
primaryKeyNew, detectedPrimaryKeyName) {
-
-            @Override
-            protected void appendDropOriginalPrimaryKeySQL(DbAdapter adapter, 
List<String> sqls) {
-                sqls.add("ALTER TABLE " + 
adapter.getQuotingStrategy().quotedFullyQualifiedName(getEntity())
-                        + " DROP PRIMARY KEY");
-            }
-
-        };
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLDBAdapter.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLDBAdapter.java 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLDBAdapter.java
index 6cfcaa5..96c5c0b 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLDBAdapter.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLDBAdapter.java
@@ -33,7 +33,6 @@ import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.DbJoin;
 import org.apache.cayenne.map.DbRelationship;
 import org.apache.cayenne.map.EntityResolver;
-import org.apache.cayenne.merge.MergerFactory;
 import org.apache.cayenne.query.Query;
 import org.apache.cayenne.query.SQLAction;
 import org.apache.cayenne.query.SelectQuery;
@@ -225,10 +224,4 @@ public class HSQLDBAdapter extends JdbcAdapter {
                        super.createTableAppendColumn(sqlBuffer, column);
                }
        }
-
-       @Override
-       public MergerFactory mergerFactory() {
-               return new HSQLMergerFactory();
-       }
-
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLMergerFactory.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLMergerFactory.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLMergerFactory.java
deleted file mode 100644
index e972b15..0000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLMergerFactory.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-package org.apache.cayenne.dba.hsqldb;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.cayenne.dba.DbAdapter;
-import org.apache.cayenne.dba.QuotingStrategy;
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.merge.MergerFactory;
-import org.apache.cayenne.merge.MergerToken;
-import org.apache.cayenne.merge.SetAllowNullToDb;
-import org.apache.cayenne.merge.SetColumnTypeToDb;
-import org.apache.cayenne.merge.SetPrimaryKeyToDb;
-
-public class HSQLMergerFactory extends MergerFactory {
-
-    @Override
-    public MergerToken createSetColumnTypeToDb(final DbEntity entity, 
DbAttribute columnOriginal,
-            final DbAttribute columnNew) {
-
-        return new SetColumnTypeToDb(entity, columnOriginal, columnNew) {
-
-            @Override
-            protected void appendPrefix(StringBuffer sqlBuffer, 
QuotingStrategy context) {
-                sqlBuffer.append("ALTER TABLE ");
-                sqlBuffer.append(context.quotedFullyQualifiedName(entity));
-                sqlBuffer.append(" ALTER ");
-                sqlBuffer.append(context.quotedName(columnNew));
-                sqlBuffer.append(" ");
-            }
-        };
-    }
-
-    @Override
-    public MergerToken createSetAllowNullToDb(DbEntity entity, DbAttribute 
column) {
-        return new SetAllowNullToDb(entity, column) {
-
-            @Override
-            public List<String> createSql(DbAdapter adapter) {
-                QuotingStrategy context = adapter.getQuotingStrategy();
-
-                return Collections.singletonList("ALTER TABLE " + 
context.quotedFullyQualifiedName(getEntity())
-                        + " ALTER COLUMN " + context.quotedName(getColumn()) + 
" NULL");
-            }
-
-        };
-    }
-
-    @Override
-    public MergerToken createSetPrimaryKeyToDb(DbEntity entity, 
Collection<DbAttribute> primaryKeyOriginal,
-            Collection<DbAttribute> primaryKeyNew, String 
detectedPrimaryKeyName) {
-        return new SetPrimaryKeyToDb(entity, primaryKeyOriginal, 
primaryKeyNew, detectedPrimaryKeyName) {
-
-            @Override
-            protected void appendDropOriginalPrimaryKeySQL(DbAdapter adapter, 
List<String> sqls) {
-                sqls.add("ALTER TABLE " + 
adapter.getQuotingStrategy().quotedFullyQualifiedName(getEntity())
-                        + " DROP PRIMARY KEY");
-            }
-
-        };
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresAdapter.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresAdapter.java 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresAdapter.java
index d9aee83..dc94bae 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresAdapter.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresAdapter.java
@@ -37,7 +37,6 @@ import org.apache.cayenne.dba.TypesMapping;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.EntityResolver;
-import org.apache.cayenne.merge.MergerFactory;
 import org.apache.cayenne.query.Query;
 import org.apache.cayenne.query.SQLAction;
 import org.apache.cayenne.query.SelectQuery;
@@ -121,11 +120,6 @@ public class IngresAdapter extends JdbcAdapter {
        }
 
        @Override
-       public MergerFactory mergerFactory() {
-               return new IngresMergerFactory();
-       }
-
-       @Override
        public void createTableAppendColumn(StringBuffer buf, DbAttribute at) {
 
                String[] types = externalTypesForJdbcType(at.getType());

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresMergerFactory.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresMergerFactory.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresMergerFactory.java
deleted file mode 100644
index f8da652..0000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresMergerFactory.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-package org.apache.cayenne.dba.ingres;
-
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.cayenne.dba.DbAdapter;
-import org.apache.cayenne.dba.QuotingStrategy;
-import org.apache.cayenne.dba.TypesMapping;
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.DbJoin;
-import org.apache.cayenne.map.DbRelationship;
-import org.apache.cayenne.merge.AddRelationshipToDb;
-import org.apache.cayenne.merge.DropColumnToDb;
-import org.apache.cayenne.merge.DropRelationshipToDb;
-import org.apache.cayenne.merge.MergerFactory;
-import org.apache.cayenne.merge.MergerToken;
-import org.apache.cayenne.merge.SetAllowNullToDb;
-import org.apache.cayenne.merge.SetColumnTypeToDb;
-import org.apache.cayenne.merge.SetNotNullToDb;
-
-public class IngresMergerFactory extends MergerFactory {
-
-    @Override
-    public MergerToken createSetColumnTypeToDb(final DbEntity entity, 
DbAttribute columnOriginal,
-            final DbAttribute columnNew) {
-
-        return new SetColumnTypeToDb(entity, columnOriginal, columnNew) {
-
-            @Override
-            protected void appendPrefix(StringBuffer sqlBuffer, 
QuotingStrategy context) {
-                sqlBuffer.append("ALTER TABLE ");
-                sqlBuffer.append(context.quotedFullyQualifiedName(entity));
-                sqlBuffer.append(" ALTER COLUMN ");
-                sqlBuffer.append(context.quotedName(columnNew));
-                sqlBuffer.append(" ");
-            }
-        };
-    }
-
-    @Override
-    public MergerToken createDropColumnToDb(DbEntity entity, DbAttribute 
column) {
-        return new DropColumnToDb(entity, column) {
-
-            @Override
-            public List<String> createSql(DbAdapter adapter) {
-                StringBuilder buf = new StringBuilder();
-                QuotingStrategy context = adapter.getQuotingStrategy();
-                buf.append("ALTER TABLE ");
-                buf.append(context.quotedFullyQualifiedName(getEntity()));
-                buf.append(" DROP COLUMN ");
-                buf.append(context.quotedName(getColumn()));
-                buf.append(" RESTRICT ");
-
-                return Collections.singletonList(buf.toString());
-            }
-
-        };
-    }
-
-    @Override
-    public MergerToken createAddRelationshipToDb(DbEntity entity, final 
DbRelationship rel) {
-        return new AddRelationshipToDb(entity, rel) {
-            @Override
-            public List<String> createSql(DbAdapter adapter) {
-                if (!rel.isToMany() && rel.isToPK() && !rel.isToDependentPK()) 
{
-
-                    DbEntity source = (DbEntity) rel.getSourceEntity();
-                    QuotingStrategy context = adapter.getQuotingStrategy();
-                    StringBuilder buf = new StringBuilder();
-                    StringBuilder refBuf = new StringBuilder();
-
-                    buf.append("ALTER TABLE ");
-                    buf.append(context.quotedFullyQualifiedName(source));
-
-                    // requires the ADD CONSTRAINT statement
-                    buf.append(" ADD CONSTRAINT ");
-                    String name = "U_" + rel.getSourceEntity().getName() + "_"
-                            + (long) (System.currentTimeMillis() / 
(Math.random() * 100000));
-
-                    buf.append(context.quotedIdentifier(rel.getSourceEntity(), 
name));
-                    buf.append(" FOREIGN KEY (");
-
-                    boolean first = true;
-                    for (DbJoin join : rel.getJoins()) {
-                        if (!first) {
-                            buf.append(", ");
-                            refBuf.append(", ");
-                        } else
-                            first = false;
-
-                        buf.append(context.quotedSourceName(join));
-                        refBuf.append(context.quotedTargetName(join));
-                    }
-
-                    buf.append(") REFERENCES ");
-                    buf.append(context.quotedFullyQualifiedName((DbEntity) 
rel.getTargetEntity()));
-                    buf.append(" (");
-                    buf.append(refBuf.toString());
-                    buf.append(')');
-
-                    // also make sure we delete dependent FKs
-                    buf.append(" ON DELETE CASCADE");
-
-                    String fksql = buf.toString();
-
-                    if (fksql != null) {
-                        return Collections.singletonList(fksql);
-                    }
-                }
-
-                return Collections.emptyList();
-
-            }
-        };
-    }
-
-    @Override
-    public MergerToken createSetNotNullToDb(DbEntity entity, DbAttribute 
column) {
-        return new SetNotNullToDb(entity, column) {
-
-            @Override
-            public List<String> createSql(DbAdapter adapter) {
-
-                /*
-                 * TODO: we generate this query as in ingres db documentation,
-                 * but unfortunately ingres don't support it
-                 */
-
-                StringBuilder sqlBuffer = new StringBuilder();
-
-                QuotingStrategy context = adapter.getQuotingStrategy();
-
-                sqlBuffer.append("ALTER TABLE ");
-                sqlBuffer.append(getEntity().getFullyQualifiedName());
-                sqlBuffer.append(" ALTER COLUMN ");
-                sqlBuffer.append(context.quotedName(getColumn()));
-                sqlBuffer.append(" ");
-                
sqlBuffer.append(adapter.externalTypesForJdbcType(getColumn().getType())[0]);
-
-                if (adapter.typeSupportsLength(getColumn().getType()) && 
getColumn().getMaxLength() > 0) {
-                    sqlBuffer.append("(");
-                    sqlBuffer.append(getColumn().getMaxLength());
-                    sqlBuffer.append(")");
-                }
-
-                sqlBuffer.append(" NOT NULL");
-
-                return Collections.singletonList(sqlBuffer.toString());
-            }
-
-        };
-    }
-
-    @Override
-    public MergerToken createSetAllowNullToDb(DbEntity entity, DbAttribute 
column) {
-        return new SetAllowNullToDb(entity, column) {
-
-            @Override
-            public List<String> createSql(DbAdapter adapter) {
-                StringBuilder sqlBuffer = new StringBuilder();
-                QuotingStrategy context = adapter.getQuotingStrategy();
-                sqlBuffer.append("ALTER TABLE ");
-                
sqlBuffer.append(context.quotedFullyQualifiedName(getEntity()));
-                sqlBuffer.append(" ALTER COLUMN ");
-                sqlBuffer.append(context.quotedName(getColumn()));
-                sqlBuffer.append(" ");
-                
sqlBuffer.append(adapter.externalTypesForJdbcType(getColumn().getType())[0]);
-
-                if (adapter.typeSupportsLength(getColumn().getType()) && 
getColumn().getMaxLength() > 0) {
-                    sqlBuffer.append("(");
-                    sqlBuffer.append(getColumn().getMaxLength());
-                    sqlBuffer.append(")");
-                }
-
-                sqlBuffer.append(" WITH NULL");
-
-                return Collections.singletonList(sqlBuffer.toString());
-            }
-
-        };
-    }
-
-    @Override
-    public MergerToken createDropRelationshipToDb(final DbEntity entity, 
DbRelationship rel) {
-
-        return new DropRelationshipToDb(entity, rel) {
-
-            @Override
-            public List<String> createSql(DbAdapter adapter) {
-                String fkName = getFkName();
-
-                if (fkName == null) {
-                    return Collections.emptyList();
-                }
-                
-                StringBuilder buf = new StringBuilder();
-                buf.append("ALTER TABLE ");
-                
buf.append(adapter.getQuotingStrategy().quotedFullyQualifiedName(getEntity()));
-                buf.append(" DROP CONSTRAINT ");
-                buf.append(fkName);
-                buf.append(" CASCADE ");
-
-                return Collections.singletonList(buf.toString());
-            }
-        };
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java
index 961f653..1ecac8a 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java
@@ -27,16 +27,23 @@ import 
org.apache.cayenne.access.translator.ejbql.JdbcEJBQLTranslatorFactory;
 import org.apache.cayenne.access.translator.select.QualifierTranslator;
 import org.apache.cayenne.access.translator.select.QueryAssembler;
 import org.apache.cayenne.access.translator.select.SelectTranslator;
-import org.apache.cayenne.access.types.*;
+import org.apache.cayenne.access.types.ByteArrayType;
+import org.apache.cayenne.access.types.CharType;
+import org.apache.cayenne.access.types.ExtendedType;
+import org.apache.cayenne.access.types.ExtendedTypeFactory;
+import org.apache.cayenne.access.types.ExtendedTypeMap;
 import org.apache.cayenne.configuration.Constants;
 import org.apache.cayenne.configuration.RuntimeProperties;
-import org.apache.cayenne.dba.*;
+import org.apache.cayenne.dba.DefaultQuotingStrategy;
+import org.apache.cayenne.dba.JdbcAdapter;
+import org.apache.cayenne.dba.PkGenerator;
+import org.apache.cayenne.dba.QuotingStrategy;
+import org.apache.cayenne.dba.TypesMapping;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.DbRelationship;
 import org.apache.cayenne.map.EntityResolver;
-import org.apache.cayenne.merge.MergerFactory;
 import org.apache.cayenne.query.Query;
 import org.apache.cayenne.query.SQLAction;
 import org.apache.cayenne.query.SelectQuery;
@@ -45,7 +52,13 @@ import org.apache.cayenne.resource.ResourceLocator;
 import java.sql.PreparedStatement;
 import java.sql.SQLException;
 import java.sql.Types;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
 
 /**
  * DbAdapter implementation for <a href="http://www.mysql.com";>MySQL RDBMS</a>.
@@ -378,11 +391,6 @@ public class MySQLAdapter extends JdbcAdapter {
                }
        }
 
-       @Override
-       public MergerFactory mergerFactory() {
-               return new MySQLMergerFactory();
-       }
-
        final class PKComparator implements Comparator<DbAttribute> {
 
                public int compare(DbAttribute a1, DbAttribute a2) {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLMergerFactory.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLMergerFactory.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLMergerFactory.java
deleted file mode 100644
index 43f4b55..0000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLMergerFactory.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-package org.apache.cayenne.dba.mysql;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.cayenne.dba.DbAdapter;
-import org.apache.cayenne.dba.QuotingStrategy;
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.DbRelationship;
-import org.apache.cayenne.merge.DropRelationshipToDb;
-import org.apache.cayenne.merge.MergerFactory;
-import org.apache.cayenne.merge.MergerToken;
-import org.apache.cayenne.merge.SetAllowNullToDb;
-import org.apache.cayenne.merge.SetColumnTypeToDb;
-import org.apache.cayenne.merge.SetNotNullToDb;
-import org.apache.cayenne.merge.SetPrimaryKeyToDb;
-
-public class MySQLMergerFactory extends MergerFactory {
-
-    @Override
-    public MergerToken createSetNotNullToDb(
-            final DbEntity entity,
-            final DbAttribute column) {
-        return new SetNotNullToDb(entity, column) {
-
-            @Override
-            public List<String> createSql(DbAdapter adapter) {
-                StringBuffer sqlBuffer = new StringBuffer();
-
-                QuotingStrategy context = adapter.getQuotingStrategy();
-
-                sqlBuffer.append("ALTER TABLE ");
-                
sqlBuffer.append(context.quotedFullyQualifiedName(getEntity()));
-                sqlBuffer.append(" CHANGE ");
-                sqlBuffer.append(context.quotedName(getColumn()));
-                sqlBuffer.append(" ");
-                adapter.createTableAppendColumn(sqlBuffer, column);
-
-                return Collections.singletonList(sqlBuffer.toString());
-            }
-
-        };
-    }
-
-    @Override
-    public MergerToken createSetAllowNullToDb(
-            final DbEntity entity,
-            final DbAttribute column) {
-        return new SetAllowNullToDb(entity, column) {
-
-            @Override
-            public List<String> createSql(DbAdapter adapter) {
-                StringBuffer sqlBuffer = new StringBuffer();
-
-                QuotingStrategy context = adapter.getQuotingStrategy();
-
-                sqlBuffer.append("ALTER TABLE ");
-                
sqlBuffer.append(context.quotedFullyQualifiedName(getEntity()));
-                sqlBuffer.append(" CHANGE ");
-                sqlBuffer.append(context.quotedName(getColumn()));
-                sqlBuffer.append(" ");
-                adapter.createTableAppendColumn(sqlBuffer, column);
-
-                return Collections.singletonList(sqlBuffer.toString());
-            }
-
-        };
-    }
-
-    @Override
-    public MergerToken createSetColumnTypeToDb(
-            final DbEntity entity,
-            DbAttribute columnOriginal,
-            final DbAttribute columnNew) {
-
-        return new SetColumnTypeToDb(entity, columnOriginal, columnNew) {
-
-            @Override
-            protected void appendPrefix(StringBuffer sqlBuffer, 
QuotingStrategy context) {
-                // 
http://dev.mysql.com/tech-resources/articles/mysql-cluster-50.html
-                sqlBuffer.append("ALTER TABLE ");
-                sqlBuffer.append(context.quotedFullyQualifiedName(entity));
-                sqlBuffer.append(" MODIFY ");
-                sqlBuffer.append(context.quotedName(columnNew));
-                sqlBuffer.append(" ");
-            }
-
-        };
-    }
-
-    @Override
-    public MergerToken createDropRelationshipToDb(
-            final DbEntity entity,
-            DbRelationship rel) {
-
-        return new DropRelationshipToDb(entity, rel) {
-
-            @Override
-            public List<String> createSql(DbAdapter adapter) {
-                String fkName = getFkName();
-
-                if (fkName == null) {
-                    return Collections.emptyList();
-                }
-                QuotingStrategy context = adapter.getQuotingStrategy();
-
-                // 
http://dev.mysql.com/tech-resources/articles/mysql-cluster-50.html
-                return Collections.singletonList("ALTER TABLE " + 
context.quotedFullyQualifiedName(entity) + " DROP FOREIGN KEY " + fkName);
-            }
-        };
-    }
-    
-    @Override
-    public MergerToken createSetPrimaryKeyToDb(
-            DbEntity entity,
-            Collection<DbAttribute> primaryKeyOriginal,
-            Collection<DbAttribute> primaryKeyNew,
-            String detectedPrimaryKeyName) {
-        return new SetPrimaryKeyToDb(
-                entity,
-                primaryKeyOriginal,
-                primaryKeyNew,
-                detectedPrimaryKeyName) {
-
-            @Override
-            protected void appendDropOriginalPrimaryKeySQL(
-                    DbAdapter adapter,
-                    List<String> sqls) {
-                sqls.add("ALTER TABLE "
-                        + adapter.getQuotingStrategy()
-                                .quotedFullyQualifiedName(getEntity())
-                        + " DROP PRIMARY KEY");
-            }
-
-        };
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/openbase/OpenBaseAdapter.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/openbase/OpenBaseAdapter.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/openbase/OpenBaseAdapter.java
index c4a50db..a426332 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/openbase/OpenBaseAdapter.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/openbase/OpenBaseAdapter.java
@@ -39,7 +39,6 @@ import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.DbJoin;
 import org.apache.cayenne.map.DbRelationship;
 import org.apache.cayenne.map.EntityResolver;
-import org.apache.cayenne.merge.MergerFactory;
 import org.apache.cayenne.query.SelectQuery;
 import org.apache.cayenne.resource.ResourceLocator;
 
@@ -53,251 +52,245 @@ import java.util.List;
 /**
  * DbAdapter implementation for <a href="http://www.openbase.com";>OpenBase</a>.
  * Sample connection settings to use with OpenBase are shown below:
- * 
+ * <p>
  * <pre>
  * openbase.jdbc.username = test
  * openbase.jdbc.password = secret
  * openbase.jdbc.url = jdbc:openbase://serverhostname/cayenne
  * openbase.jdbc.driver = com.openbase.jdbc.ObDriver
  * </pre>
- * 
+ *
  * @since 1.1
  */
 public class OpenBaseAdapter extends JdbcAdapter {
 
-       public OpenBaseAdapter(@Inject RuntimeProperties runtimeProperties,
-                       @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) 
List<ExtendedType> defaultExtendedTypes,
-                       @Inject(Constants.SERVER_USER_TYPES_LIST) 
List<ExtendedType> userExtendedTypes,
-                       @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) 
List<ExtendedTypeFactory> extendedTypeFactories,
-                       @Inject(Constants.SERVER_RESOURCE_LOCATOR) 
ResourceLocator resourceLocator) {
-               super(runtimeProperties, defaultExtendedTypes, 
userExtendedTypes, extendedTypeFactories, resourceLocator);
-
-               // init defaults
-               this.setSupportsUniqueConstraints(false);
-       }
-
-       /**
-        * @since 4.0
-        */
-       @Override
-       public SelectTranslator getSelectTranslator(SelectQuery<?> query, 
EntityResolver entityResolver) {
-               return new OpenBaseSelectTranslator(query, this, 
entityResolver);
-       }
-
-       @Override
-       protected void configureExtendedTypes(ExtendedTypeMap map) {
-               super.configureExtendedTypes(map);
-
-               // Byte handling doesn't work on read...
-               // need special converter
-               map.registerType(new OpenBaseByteType());
-
-               map.registerType(new OpenBaseCharType());
-       }
-
-       @Override
-       public DbAttribute buildAttribute(String name, String typeName, int 
type, int size, int scale, boolean allowNulls) {
-
-               // OpenBase makes no distinction between CHAR and VARCHAR
-               // so lets use VARCHAR, since it seems more generic
-               if (type == Types.CHAR) {
-                       type = Types.VARCHAR;
-               }
-
-               return super.buildAttribute(name, typeName, type, size, scale, 
allowNulls);
-       }
-
-       /**
-        * Returns word "go".
-        */
-       @Override
-       public String getBatchTerminator() {
-               return "go";
-       }
-
-       /**
-        * Returns null, since views are not yet supported in openbase.
-        */
-       @Override
-       public String tableTypeForView() {
-               // TODO: according to OpenBase docs views *ARE* supported.
-               return null;
-       }
-
-       /**
-        * Returns OpenBase-specific translator for queries.
-        */
-       @Override
-       public QualifierTranslator getQualifierTranslator(QueryAssembler 
queryAssembler) {
-               return new OpenBaseQualifierTranslator(queryAssembler);
-       }
-
-       /**
-        * Creates and returns a primary key generator. Overrides superclass
-        * implementation to return an instance of OpenBasePkGenerator that uses
-        * built-in multi-server primary key generation.
-        */
-       @Override
-       protected PkGenerator createPkGenerator() {
-               return new OpenBasePkGenerator(this);
-       }
-
-       /**
-        * Returns a SQL string that can be used to create database table
-        * corresponding to <code>ent</code> parameter.
-        */
-       @Override
-       public String createTable(DbEntity ent) {
-
-               StringBuilder buf = new StringBuilder();
-
-               buf.append("CREATE TABLE ");
-               buf.append(quotingStrategy.quotedFullyQualifiedName(ent));
-               buf.append(" (");
-
-               // columns
-               Iterator<DbAttribute> it = ent.getAttributes().iterator();
-               boolean first = true;
-               while (it.hasNext()) {
-                       if (first) {
-                               first = false;
-                       } else {
-                               buf.append(", ");
-                       }
-
-                       DbAttribute at = it.next();
-
-                       // attribute may not be fully valid, do a simple check
-                       if (at.getType() == TypesMapping.NOT_DEFINED) {
-                               throw new CayenneRuntimeException("Undefined 
type for attribute '" + ent.getFullyQualifiedName() + "."
-                                               + at.getName() + "'.");
-                       }
-
-                       String[] types = externalTypesForJdbcType(at.getType());
-                       if (types == null || types.length == 0) {
-                               throw new CayenneRuntimeException("Undefined 
type for attribute '" + ent.getFullyQualifiedName() + "."
-                                               + at.getName() + "': " + 
at.getType());
-                       }
-
-                       String type = types[0];
-                       buf.append(quotingStrategy.quotedName(at)).append(' 
').append(type);
-
-                       // append size and precision (if applicable)
-                       if (typeSupportsLength(at.getType())) {
-                               int len = at.getMaxLength();
-                               int scale = 
TypesMapping.isDecimal(at.getType()) ? at.getScale() : -1;
-
-                               // sanity check
-                               if (scale > len) {
-                                       scale = -1;
-                               }
-
-                               if (len > 0) {
-                                       buf.append('(').append(len);
-
-                                       if (scale >= 0) {
-                                               buf.append(", ").append(scale);
-                                       }
-
-                                       buf.append(')');
-                               }
-                       }
-
-                       if (at.isMandatory()) {
-                               buf.append(" NOT NULL");
-                       } else {
-                               buf.append(" NULL");
-                       }
-               }
-
-               buf.append(')');
-               return buf.toString();
-       }
-
-       /**
-        * Returns a SQL string that can be used to create a foreign key 
constraint
-        * for the relationship.
-        */
-       @Override
-       public String createFkConstraint(DbRelationship rel) {
-               StringBuilder buf = new StringBuilder();
-
-               // OpendBase Specifics is that we need to create a constraint 
going
-               // from destination to source for this to work...
-
-               DbEntity sourceEntity = (DbEntity) rel.getSourceEntity();
-               DbEntity targetEntity = (DbEntity) rel.getTargetEntity();
-               String toMany = (!rel.isToMany()) ? "'1'" : "'0'";
-
-               // TODO: doesn't seem like OpenBase supports compound joins...
-               // need to doublecheck that
-
-               int joinsLen = rel.getJoins().size();
-               if (joinsLen == 0) {
-                       throw new CayenneRuntimeException("Relationship has no 
joins: " + rel.getName());
-               } else if (joinsLen > 1) {
-                       // ignore extra joins
-               }
-
-               DbJoin join = rel.getJoins().get(0);
-
-               buf.append("INSERT INTO _SYS_RELATIONSHIP 
(").append("dest_table, dest_column, source_table, source_column, ")
-                               .append("block_delete, cascade_delete, 
one_to_many, operator, relationshipName").append(") VALUES ('")
-                               
.append(sourceEntity.getFullyQualifiedName()).append("', 
'").append(join.getSourceName())
-                               .append("', 
'").append(targetEntity.getFullyQualifiedName()).append("', '")
-                               .append(join.getTargetName()).append("', 0, 0, 
").append(toMany).append(", '=', '")
-                               .append(rel.getName()).append("')");
-
-               return buf.toString();
-       }
-
-       // OpenBase JDBC driver has trouble reading "integer" as byte
-       // this converter addresses such problem
-       static class OpenBaseByteType extends ByteType {
-
-               OpenBaseByteType() {
-                       super(true);
-               }
-
-               @Override
-               public Object materializeObject(ResultSet rs, int index, int 
type) throws Exception {
-
-                       // read value as int, and then narrow it down
-                       int val = rs.getInt(index);
-                       return (rs.wasNull()) ? null : Byte.valueOf((byte) val);
-               }
-
-               @Override
-               public Object materializeObject(CallableStatement rs, int 
index, int type) throws Exception {
-
-                       // read value as int, and then narrow it down
-                       int val = rs.getInt(index);
-                       return (rs.wasNull()) ? null : Byte.valueOf((byte) val);
-               }
-       }
-
-       static class OpenBaseCharType extends CharType {
-
-               OpenBaseCharType() {
-                       super(false, true);
-               }
-
-               @Override
-               public void setJdbcObject(PreparedStatement st, Object val, int 
pos, int type, int precision) throws Exception {
-
-                       // These to types map to "text"; and when setting 
"text" as object
-                       // OB assumes that the object is the actual CLOB... 
weird
-                       if (type == Types.CLOB || type == Types.LONGVARCHAR) {
-                               st.setString(pos, (String) val);
-                       } else {
-                               super.setJdbcObject(st, val, pos, type, 
precision);
-                       }
-               }
-       }
-
-       @Override
-       public MergerFactory mergerFactory() {
-               return new OpenBaseMergerFactory();
-       }
-
+    public OpenBaseAdapter(@Inject RuntimeProperties runtimeProperties,
+                           @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) 
List<ExtendedType> defaultExtendedTypes,
+                           @Inject(Constants.SERVER_USER_TYPES_LIST) 
List<ExtendedType> userExtendedTypes,
+                           @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) 
List<ExtendedTypeFactory> extendedTypeFactories,
+                           @Inject(Constants.SERVER_RESOURCE_LOCATOR) 
ResourceLocator resourceLocator) {
+        super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, 
extendedTypeFactories, resourceLocator);
+
+        // init defaults
+        this.setSupportsUniqueConstraints(false);
+    }
+
+    /**
+     * @since 4.0
+     */
+    @Override
+    public SelectTranslator getSelectTranslator(SelectQuery<?> query, 
EntityResolver entityResolver) {
+        return new OpenBaseSelectTranslator(query, this, entityResolver);
+    }
+
+    @Override
+    protected void configureExtendedTypes(ExtendedTypeMap map) {
+        super.configureExtendedTypes(map);
+
+        // Byte handling doesn't work on read...
+        // need special converter
+        map.registerType(new OpenBaseByteType());
+
+        map.registerType(new OpenBaseCharType());
+    }
+
+    @Override
+    public DbAttribute buildAttribute(String name, String typeName, int type, 
int size, int scale, boolean allowNulls) {
+
+        // OpenBase makes no distinction between CHAR and VARCHAR
+        // so lets use VARCHAR, since it seems more generic
+        if (type == Types.CHAR) {
+            type = Types.VARCHAR;
+        }
+
+        return super.buildAttribute(name, typeName, type, size, scale, 
allowNulls);
+    }
+
+    /**
+     * Returns word "go".
+     */
+    @Override
+    public String getBatchTerminator() {
+        return "go";
+    }
+
+    /**
+     * Returns null, since views are not yet supported in openbase.
+     */
+    @Override
+    public String tableTypeForView() {
+        // TODO: according to OpenBase docs views *ARE* supported.
+        return null;
+    }
+
+    /**
+     * Returns OpenBase-specific translator for queries.
+     */
+    @Override
+    public QualifierTranslator getQualifierTranslator(QueryAssembler 
queryAssembler) {
+        return new OpenBaseQualifierTranslator(queryAssembler);
+    }
+
+    /**
+     * Creates and returns a primary key generator. Overrides superclass
+     * implementation to return an instance of OpenBasePkGenerator that uses
+     * built-in multi-server primary key generation.
+     */
+    @Override
+    protected PkGenerator createPkGenerator() {
+        return new OpenBasePkGenerator(this);
+    }
+
+    /**
+     * Returns a SQL string that can be used to create database table
+     * corresponding to <code>ent</code> parameter.
+     */
+    @Override
+    public String createTable(DbEntity ent) {
+
+        StringBuilder buf = new StringBuilder();
+
+        buf.append("CREATE TABLE ");
+        buf.append(quotingStrategy.quotedFullyQualifiedName(ent));
+        buf.append(" (");
+
+        // columns
+        Iterator<DbAttribute> it = ent.getAttributes().iterator();
+        boolean first = true;
+        while (it.hasNext()) {
+            if (first) {
+                first = false;
+            } else {
+                buf.append(", ");
+            }
+
+            DbAttribute at = it.next();
+
+            // attribute may not be fully valid, do a simple check
+            if (at.getType() == TypesMapping.NOT_DEFINED) {
+                throw new CayenneRuntimeException("Undefined type for 
attribute '" + ent.getFullyQualifiedName() + "."
+                        + at.getName() + "'.");
+            }
+
+            String[] types = externalTypesForJdbcType(at.getType());
+            if (types == null || types.length == 0) {
+                throw new CayenneRuntimeException("Undefined type for 
attribute '" + ent.getFullyQualifiedName() + "."
+                        + at.getName() + "': " + at.getType());
+            }
+
+            String type = types[0];
+            buf.append(quotingStrategy.quotedName(at)).append(' 
').append(type);
+
+            // append size and precision (if applicable)
+            if (typeSupportsLength(at.getType())) {
+                int len = at.getMaxLength();
+                int scale = TypesMapping.isDecimal(at.getType()) ? 
at.getScale() : -1;
+
+                // sanity check
+                if (scale > len) {
+                    scale = -1;
+                }
+
+                if (len > 0) {
+                    buf.append('(').append(len);
+
+                    if (scale >= 0) {
+                        buf.append(", ").append(scale);
+                    }
+
+                    buf.append(')');
+                }
+            }
+
+            if (at.isMandatory()) {
+                buf.append(" NOT NULL");
+            } else {
+                buf.append(" NULL");
+            }
+        }
+
+        buf.append(')');
+        return buf.toString();
+    }
+
+    /**
+     * Returns a SQL string that can be used to create a foreign key constraint
+     * for the relationship.
+     */
+    @Override
+    public String createFkConstraint(DbRelationship rel) {
+        StringBuilder buf = new StringBuilder();
+
+        // OpendBase Specifics is that we need to create a constraint going
+        // from destination to source for this to work...
+
+        DbEntity sourceEntity = (DbEntity) rel.getSourceEntity();
+        DbEntity targetEntity = (DbEntity) rel.getTargetEntity();
+        String toMany = (!rel.isToMany()) ? "'1'" : "'0'";
+
+        // TODO: doesn't seem like OpenBase supports compound joins...
+        // need to doublecheck that
+
+        int joinsLen = rel.getJoins().size();
+        if (joinsLen == 0) {
+            throw new CayenneRuntimeException("Relationship has no joins: " + 
rel.getName());
+        } else if (joinsLen > 1) {
+            // ignore extra joins
+        }
+
+        DbJoin join = rel.getJoins().get(0);
+
+        buf.append("INSERT INTO _SYS_RELATIONSHIP (").append("dest_table, 
dest_column, source_table, source_column, ")
+                .append("block_delete, cascade_delete, one_to_many, operator, 
relationshipName").append(") VALUES ('")
+                .append(sourceEntity.getFullyQualifiedName()).append("', 
'").append(join.getSourceName())
+                .append("', 
'").append(targetEntity.getFullyQualifiedName()).append("', '")
+                .append(join.getTargetName()).append("', 0, 0, 
").append(toMany).append(", '=', '")
+                .append(rel.getName()).append("')");
+
+        return buf.toString();
+    }
+
+    // OpenBase JDBC driver has trouble reading "integer" as byte
+    // this converter addresses such problem
+    static class OpenBaseByteType extends ByteType {
+
+        OpenBaseByteType() {
+            super(true);
+        }
+
+        @Override
+        public Object materializeObject(ResultSet rs, int index, int type) 
throws Exception {
+
+            // read value as int, and then narrow it down
+            int val = rs.getInt(index);
+            return (rs.wasNull()) ? null : Byte.valueOf((byte) val);
+        }
+
+        @Override
+        public Object materializeObject(CallableStatement rs, int index, int 
type) throws Exception {
+
+            // read value as int, and then narrow it down
+            int val = rs.getInt(index);
+            return (rs.wasNull()) ? null : Byte.valueOf((byte) val);
+        }
+    }
+
+    static class OpenBaseCharType extends CharType {
+
+        OpenBaseCharType() {
+            super(false, true);
+        }
+
+        @Override
+        public void setJdbcObject(PreparedStatement st, Object val, int pos, 
int type, int precision) throws Exception {
+
+            // These to types map to "text"; and when setting "text" as object
+            // OB assumes that the object is the actual CLOB... weird
+            if (type == Types.CLOB || type == Types.LONGVARCHAR) {
+                st.setString(pos, (String) val);
+            } else {
+                super.setJdbcObject(st, val, pos, type, precision);
+            }
+        }
+    }
 }

Reply via email to