http://git-wip-us.apache.org/repos/asf/cayenne/blob/13d0da53/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectTreeModel.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectTreeModel.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectTreeModel.java
index 8a26199..08e4de3 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectTreeModel.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectTreeModel.java
@@ -19,6 +19,14 @@
 
 package org.apache.cayenne.modeler;
 
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.Map;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.MutableTreeNode;
+
 import org.apache.cayenne.configuration.DataNodeDescriptor;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.DbEntity;
@@ -28,201 +36,182 @@ import org.apache.cayenne.map.Procedure;
 import org.apache.cayenne.project.Project;
 import org.apache.cayenne.query.Query;
 
-import javax.swing.tree.DefaultMutableTreeNode;
-import javax.swing.tree.DefaultTreeModel;
-import javax.swing.tree.MutableTreeNode;
-import java.util.Comparator;
-import java.util.Enumeration;
-import java.util.HashMap;
-
-
 /**
  * ProjectTreeModel is a model of Cayenne project tree.
  */
 public class ProjectTreeModel extends DefaultTreeModel {
 
-       private Filter filter=new Filter();
+       private Filter filter = new Filter();
+
+       /**
+        * Constructor for ProjectTreeModel.
+        */
+       public ProjectTreeModel(Project project) {
+               
super(ProjectTreeFactory.wrapProjectNode(project.getRootNode()));
+       }
+
+       /**
+        * Re-inserts a tree node to preserve the correct ordering of items. 
Assumes
+        * that the tree is already ordered, except for one node.
+        */
+       public void positionNode(MutableTreeNode parent, DefaultMutableTreeNode 
treeNode, Comparator comparator) {
+
+               if (treeNode == null) {
+                       return;
+               }
+
+               if (parent == null && treeNode != getRoot()) {
+                       parent = (MutableTreeNode) treeNode.getParent();
+                       if (parent == null) {
+                               parent = getRootNode();
+                       }
+               }
+
+               Object object = treeNode.getUserObject();
+
+               if (parent != null) {
+                       int len = parent.getChildCount();
+                       int ins = -1;
+                       int rm = -1;
+
+                       for (int i = 0; i < len; i++) {
+                               DefaultMutableTreeNode node = 
(DefaultMutableTreeNode) parent.getChildAt(i);
+
+                               // remember to remove node
+                               if (node == treeNode) {
+                                       rm = i;
+                                       continue;
+                               }
+
+                               // no more insert checks
+                               if (ins >= 0) {
+                                       continue;
+                               }
+
+                               // ObjEntities go before DbEntities
+                               if (comparator.compare(object, 
node.getUserObject()) <= 0) {
+                                       ins = i;
+                               }
+                       }
+
+                       if (ins < 0) {
+                               ins = len;
+                       }
+
+                       if (rm == ins) {
+                               return;
+                       }
+
+                       // remove
+                       if (rm >= 0) {
+                               removeNodeFromParent(treeNode);
+                               if (rm < ins) {
+                                       ins--;
+                               }
+                       }
+                       try {
+                               // insert
+                               insertNodeInto(treeNode, parent, ins);
+                       } catch (NullPointerException e) {
+
+                       }
+               }
+       }
 
        /**
-     * Constructor for ProjectTreeModel.
-     */
-    public ProjectTreeModel(Project project) {
-        super(ProjectTreeFactory.wrapProjectNode(project.getRootNode()));
-    }
-
-    /**
-     * Re-inserts a tree node to preserve the correct ordering of items. 
Assumes that the
-     * tree is already ordered, except for one node.
-     */
-    public void positionNode(
-            MutableTreeNode parent,
-            DefaultMutableTreeNode treeNode,
-            Comparator comparator) {
-
-        if (treeNode == null) {
-            return;
-        }
-
-        if (parent == null && treeNode != getRoot()) {
-            parent = (MutableTreeNode) treeNode.getParent();
-            if (parent == null) {
-                parent = getRootNode();
-            }
-        }
-
-        Object object = treeNode.getUserObject();
-
-        if (parent != null) {
-            int len = parent.getChildCount();
-            int ins = -1;
-            int rm = -1;
-
-            for (int i = 0; i < len; i++) {
-                DefaultMutableTreeNode node = (DefaultMutableTreeNode) parent
-                        .getChildAt(i);
-
-                // remember to remove node
-                if (node == treeNode) {
-                    rm = i;
-                    continue;
-                }
-
-                // no more insert checks
-                if (ins >= 0) {
-                    continue;
-                }
-
-                // ObjEntities go before DbEntities
-                if (comparator.compare(object, node.getUserObject()) <= 0) {
-                    ins = i;
-                }
-            }
-
-            if (ins < 0) {
-                ins = len;
-            }
-
-            if (rm == ins) {
-                return;
-            }
-
-            // remove
-            if (rm >= 0) {
-                removeNodeFromParent(treeNode);
-                if (rm < ins) {
-                    ins--;
-                }
-            }
-           try{
-            // insert
-            insertNodeInto(treeNode, parent, ins);
-           }
-           catch(NullPointerException e){
-
-           }
-        }
-    }
-
-    /**
-     * Returns root node cast into DefaultMutableTreeNode.
-     */
-    public DefaultMutableTreeNode getRootNode() {
-        return (DefaultMutableTreeNode) super.getRoot();
-    }
-
-    public DefaultMutableTreeNode getNodeForObjectPath(Object[] path) {
-        if (path == null || path.length == 0) {
-            return null;
-        }
-
-        DefaultMutableTreeNode currentNode = getRootNode();
-
-        // adjust for root node being in the path
-        int start = 0;
-        if (currentNode.getUserObject() == path[0]) {
-            start = 1;
-        }
-
-        for (int i = start; i < path.length; i++) {
-            DefaultMutableTreeNode foundNode = null;
-            Enumeration children = currentNode.children();
-            while (children.hasMoreElements()) {
-                DefaultMutableTreeNode child = (DefaultMutableTreeNode) 
children
-                        .nextElement();
-                if (child.getUserObject() == path[i]) {
-                    foundNode = child;
-                    break;
-                }
-            }
-
-            if (foundNode == null) {
-                return null;
-            }
-            else {
-                currentNode = foundNode;
-            }
-        }
-
-        return currentNode;
-    }
-
-
-    public void setFiltered(HashMap<String,Boolean> filterMap) {
-       filter.setFilterMap(filterMap);
-    }
-
-
-      public int getChildCount(Object parent) {
-         int realCount = super.getChildCount(parent), filterCount =0;
-
-         for (int i=0; i<realCount; i++) {
-                 DefaultMutableTreeNode dmtn = 
(DefaultMutableTreeNode)super.getChild(parent,i);
-                 if (filter.pass(dmtn)) {
-                         filterCount++;
-                 }
-         }
-         return filterCount;
-      }
-
-      public Object getChild(Object parent, int index) {
-         int cnt=-1;
-         for (int i=0; i<super.getChildCount(parent); i++) {
-                 Object child = super.getChild(parent,i);
-                 if (filter.pass(child)) {
-                         cnt++;
-                 }
-                 if (cnt==index) {
-                         return child;
-                 }
-         }
-         return null;
-      }
-
-      class Filter {
-         private HashMap<String, Boolean> filterMap;
-         boolean pass=true;
-
-         public void setFilterMap(HashMap<String, Boolean> filterMap) {
-                 this.filterMap=filterMap;
-                 pass=false;
-         }
-
-         public boolean pass(Object obj) {
-                Object root = ((DefaultMutableTreeNode) obj).getUserObject();
-                Object firstLeaf = ((DefaultMutableTreeNode) 
obj).getFirstLeaf().getUserObject();
-
-                return ((pass) ||
-                                (root instanceof DataMap) ||
-                                (root instanceof DataNodeDescriptor) ||
-                                (firstLeaf instanceof DbEntity   && 
filterMap.get("dbEntity"))   ||
-                                (firstLeaf instanceof ObjEntity  && 
filterMap.get("objEntity"))  ||
-                                (firstLeaf instanceof Embeddable && 
filterMap.get("embeddable")) ||
-                                (firstLeaf instanceof Query      && 
filterMap.get("query"))      ||
-                                (firstLeaf instanceof Procedure  && 
filterMap.get("procedure")));
-         }
-
-         public boolean isFiltered() {
-                 return pass;
-         }
-       }
+        * Returns root node cast into DefaultMutableTreeNode.
+        */
+       public DefaultMutableTreeNode getRootNode() {
+               return (DefaultMutableTreeNode) super.getRoot();
+       }
+
+       public DefaultMutableTreeNode getNodeForObjectPath(Object[] path) {
+               if (path == null || path.length == 0) {
+                       return null;
+               }
+
+               DefaultMutableTreeNode currentNode = getRootNode();
+
+               // adjust for root node being in the path
+               int start = 0;
+               if (currentNode.getUserObject() == path[0]) {
+                       start = 1;
+               }
+
+               for (int i = start; i < path.length; i++) {
+                       DefaultMutableTreeNode foundNode = null;
+                       Enumeration children = currentNode.children();
+                       while (children.hasMoreElements()) {
+                               DefaultMutableTreeNode child = 
(DefaultMutableTreeNode) children.nextElement();
+                               if (child.getUserObject() == path[i]) {
+                                       foundNode = child;
+                                       break;
+                               }
+                       }
+
+                       if (foundNode == null) {
+                               return null;
+                       } else {
+                               currentNode = foundNode;
+                       }
+               }
+
+               return currentNode;
+       }
+
+       public void setFiltered(Map<String, Boolean> filterMap) {
+               filter.setFilterMap(filterMap);
+       }
+
+       public int getChildCount(Object parent) {
+               int realCount = super.getChildCount(parent), filterCount = 0;
+
+               for (int i = 0; i < realCount; i++) {
+                       DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode) 
super.getChild(parent, i);
+                       if (filter.pass(dmtn)) {
+                               filterCount++;
+                       }
+               }
+               return filterCount;
+       }
+
+       public Object getChild(Object parent, int index) {
+               int cnt = -1;
+               for (int i = 0; i < super.getChildCount(parent); i++) {
+                       Object child = super.getChild(parent, i);
+                       if (filter.pass(child)) {
+                               cnt++;
+                       }
+                       if (cnt == index) {
+                               return child;
+                       }
+               }
+               return null;
+       }
+
+       class Filter {
+               private Map<String, Boolean> filterMap;
+               boolean pass = true;
+
+               public void setFilterMap(Map<String, Boolean> filterMap) {
+                       this.filterMap = filterMap;
+                       pass = false;
+               }
+
+               public boolean pass(Object obj) {
+                       Object root = ((DefaultMutableTreeNode) 
obj).getUserObject();
+                       Object firstLeaf = ((DefaultMutableTreeNode) 
obj).getFirstLeaf().getUserObject();
+
+                       return ((pass) || (root instanceof DataMap) || (root 
instanceof DataNodeDescriptor)
+                                       || (firstLeaf instanceof DbEntity && 
filterMap.get("dbEntity"))
+                                       || (firstLeaf instanceof ObjEntity && 
filterMap.get("objEntity"))
+                                       || (firstLeaf instanceof Embeddable && 
filterMap.get("embeddable"))
+                                       || (firstLeaf instanceof Query && 
filterMap.get("query")) || (firstLeaf instanceof Procedure && filterMap
+                                       .get("procedure")));
+               }
+
+               public boolean isFiltered() {
+                       return pass;
+               }
+       }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/13d0da53/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/DefaultActionManager.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/DefaultActionManager.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/DefaultActionManager.java
index c9c3ede..c625bb4 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/DefaultActionManager.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/DefaultActionManager.java
@@ -57,7 +57,7 @@ public class DefaultActionManager implements ActionManager {
 
     public DefaultActionManager(@Inject Application application) {
         initActions();
-        this.actionMap = new HashMap<String, Action>(40);
+        this.actionMap = new HashMap<>(40);
 
         registerAction(new ProjectAction(application));
         registerAction(new NewProjectAction(application)).setAlwaysOn(true);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/13d0da53/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/PasteAction.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/PasteAction.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/PasteAction.java
index ebfabab..fbddf98 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/PasteAction.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/PasteAction.java
@@ -181,10 +181,10 @@ public class PasteAction extends CayenneAction implements 
FlavorListener {
 
             // add some intelligence - if we rename an entity, we should 
rename all links
             // to it as well
-            Map<String, String> renamedDbEntities = new HashMap<String, 
String>();
-            Map<String, String> renamedObjEntities = new HashMap<String, 
String>();
+            Map<String, String> renamedDbEntities = new HashMap<>();
+            Map<String, String> renamedObjEntities = new HashMap<>();
 
-            Map<String, String> renamedEmbeddables = new HashMap<String, 
String>();
+            Map<String, String> renamedEmbeddables = new HashMap<>();
 
             for (DbEntity dbEntity : dataMap.getDbEntities()) {
                 String oldName = dbEntity.getName();

http://git-wip-us.apache.org/repos/asf/cayenne/blob/13d0da53/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/CustomModeController.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/CustomModeController.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/CustomModeController.java
index 3de74ae..88781f6 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/CustomModeController.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/codegen/CustomModeController.java
@@ -19,16 +19,6 @@
 
 package org.apache.cayenne.modeler.dialog.codegen;
 
-import org.apache.cayenne.gen.ClassGenerationAction;
-import org.apache.cayenne.map.DataMap;
-import org.apache.cayenne.modeler.CodeTemplateManager;
-import org.apache.cayenne.modeler.dialog.pref.PreferenceDialog;
-import org.apache.cayenne.modeler.pref.DataMapDefaults;
-import org.apache.cayenne.swing.BindingBuilder;
-import org.apache.cayenne.swing.ObjectBinding;
-import org.apache.cayenne.util.Util;
-
-import javax.swing.DefaultComboBoxModel;
 import java.awt.Component;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -40,244 +30,221 @@ import java.util.Map.Entry;
 import java.util.Set;
 import java.util.TreeMap;
 
+import javax.swing.DefaultComboBoxModel;
+
+import org.apache.cayenne.gen.ClassGenerationAction;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.modeler.CodeTemplateManager;
+import org.apache.cayenne.modeler.dialog.pref.PreferenceDialog;
+import org.apache.cayenne.modeler.pref.DataMapDefaults;
+import org.apache.cayenne.swing.BindingBuilder;
+import org.apache.cayenne.swing.ObjectBinding;
+import org.apache.cayenne.util.Util;
+
 /**
  * A controller for the custom generation mode.
  */
 public class CustomModeController extends GeneratorController {
 
-    // correspond to non-public constants on MapClassGenerator.
-    static final String MODE_DATAMAP = "datamap";
-    static final String MODE_ENTITY = "entity";
-    static final String MODE_ALL = "all";
+       // correspond to non-public constants on MapClassGenerator.
+       static final String MODE_DATAMAP = "datamap";
+       static final String MODE_ENTITY = "entity";
+       static final String MODE_ALL = "all";
+
+       static final String DATA_MAP_MODE_LABEL = "DataMap generation";
+       static final String ENTITY_MODE_LABEL = "Entity and Embeddable 
generation";
+       static final String ALL_MODE_LABEL = "Generate all";
+
+       static final Map<String, String> modesByLabel = new HashMap<>();
+
+       static {
+               modesByLabel.put(DATA_MAP_MODE_LABEL, MODE_DATAMAP);
+               modesByLabel.put(ENTITY_MODE_LABEL, MODE_ENTITY);
+               modesByLabel.put(ALL_MODE_LABEL, MODE_ALL);
+       }
+
+       protected CustomModePanel view;
+       protected CodeTemplateManager templateManager;
+
+       protected ObjectBinding superTemplate;
+       protected ObjectBinding subTemplate;
+
+       private CustomPreferencesUpdater preferencesUpdater;
+
+       public CustomPreferencesUpdater getCustomPreferencesUpdater() {
+               return preferencesUpdater;
+       }
+
+       public CustomModeController(CodeGeneratorControllerBase parent) {
+               super(parent);
+
+               Object[] modeChoices = new Object[] { ENTITY_MODE_LABEL, 
DATA_MAP_MODE_LABEL, ALL_MODE_LABEL };
+               view.getGenerationMode().setModel(new 
DefaultComboBoxModel(modeChoices));
+
+               // bind preferences and init defaults...
+
+               Set<Entry<DataMap, DataMapDefaults>> entities = 
getMapPreferences().entrySet();
+
+               for (Entry<DataMap, DataMapDefaults> entry : entities) {
+
+                       if 
(Util.isEmptyString(entry.getValue().getSuperclassTemplate())) {
+                               
entry.getValue().setSuperclassTemplate(CodeTemplateManager.STANDARD_SERVER_SUPERCLASS);
+                       }
+
+                       if 
(Util.isEmptyString(entry.getValue().getSubclassTemplate())) {
+                               
entry.getValue().setSubclassTemplate(CodeTemplateManager.STANDARD_SERVER_SUBCLASS);
+                       }
+
+                       if 
(Util.isEmptyString(entry.getValue().getProperty("mode"))) {
+                               entry.getValue().setProperty("mode", 
MODE_ENTITY);
+                       }
+
+                       if 
(Util.isEmptyString(entry.getValue().getProperty("overwrite"))) {
+                               
entry.getValue().setBooleanProperty("overwrite", false);
+                       }
+
+                       if 
(Util.isEmptyString(entry.getValue().getProperty("pairs"))) {
+                               entry.getValue().setBooleanProperty("pairs", 
true);
+                       }
+
+                       if 
(Util.isEmptyString(entry.getValue().getProperty("usePackagePath"))) {
+                               
entry.getValue().setBooleanProperty("usePackagePath", true);
+                       }
+
+                       if 
(Util.isEmptyString(entry.getValue().getProperty("outputPattern"))) {
+                               entry.getValue().setProperty("outputPattern", 
"*.java");
+                       }
+               }
+
+               BindingBuilder builder = new 
BindingBuilder(getApplication().getBindingFactory(), this);
+
+               builder.bindToAction(view.getManageTemplatesLink(), 
"popPreferencesAction()");
+
+               builder.bindToComboSelection(view.getGenerationMode(), 
"customPreferencesUpdater.mode").updateView();
+
+               builder.bindToStateChange(view.getOverwrite(), 
"customPreferencesUpdater.overwrite").updateView();
+
+               builder.bindToStateChange(view.getPairs(), 
"customPreferencesUpdater.pairs").updateView();
+
+               builder.bindToStateChange(view.getUsePackagePath(), 
"customPreferencesUpdater.usePackagePath").updateView();
+
+               subTemplate = 
builder.bindToComboSelection(view.getSubclassTemplate(),
+                               "customPreferencesUpdater.subclassTemplate");
+
+               superTemplate = 
builder.bindToComboSelection(view.getSuperclassTemplate(),
+                               "customPreferencesUpdater.superclassTemplate");
+
+               builder.bindToTextField(view.getOutputPattern(), 
"customPreferencesUpdater.outputPattern").updateView();
+
+               builder.bindToStateChange(view.getCreatePropertyNames(), 
"customPreferencesUpdater.createPropertyNames")
+                               .updateView();
+
+               updateTemplates();
+       }
+
+       protected void createDefaults() {
+               TreeMap<DataMap, DataMapDefaults> map = new TreeMap<DataMap, 
DataMapDefaults>();
+               Collection<DataMap> dataMaps = 
getParentController().getDataMaps();
+               for (DataMap dataMap : dataMaps) {
+                       DataMapDefaults preferences;
+                       preferences = 
getApplication().getFrameController().getProjectController()
+                                       
.getDataMapPreferences(this.getClass().getName().replace(".", "/"), dataMap);
+                       preferences.setSuperclassPackage("");
+                       preferences.updateSuperclassPackage(dataMap, false);
+
+                       map.put(dataMap, preferences);
+
+                       if (getOutputPath() == null) {
+                               setOutputPath(preferences.getOutputPath());
+                       }
+               }
+
+               setMapPreferences(map);
+               preferencesUpdater = new CustomPreferencesUpdater(map);
+       }
+
+       protected GeneratorControllerPanel createView() {
+               this.view = new CustomModePanel();
+
+               Set<Entry<DataMap, DataMapDefaults>> entities = 
getMapPreferences().entrySet();
+               for (Entry<DataMap, DataMapDefaults> entry : entities) {
+                       StandardPanelComponent dataMapLine = 
createDataMapLineBy(entry.getKey(), entry.getValue());
+                       
dataMapLine.getDataMapName().setText(dataMapLine.getDataMap().getName());
+                       BindingBuilder builder = new 
BindingBuilder(getApplication().getBindingFactory(), dataMapLine);
+                       
builder.bindToTextField(dataMapLine.getSuperclassPackage(), 
"preferences.superclassPackage").updateView();
+                       this.view.addDataMapLine(dataMapLine);
+               }
+               return view;
+       }
+
+       private StandardPanelComponent createDataMapLineBy(DataMap dataMap, 
DataMapDefaults preferences) {
+               StandardPanelComponent dataMapLine = new 
StandardPanelComponent();
+               dataMapLine.setDataMap(dataMap);
+               dataMapLine.setPreferences(preferences);
+
+               return dataMapLine;
+       }
 
-    static final String DATA_MAP_MODE_LABEL = "DataMap generation";
-    static final String ENTITY_MODE_LABEL = "Entity and Embeddable generation";
-    static final String ALL_MODE_LABEL = "Generate all";
+       protected void updateTemplates() {
+               this.templateManager = 
getApplication().getCodeTemplateManager();
 
-    static final Map<String, String> modesByLabel = new HashMap<String, 
String>();
+               List<String> customTemplates = new 
ArrayList<String>(templateManager.getCustomTemplates().keySet());
+               Collections.sort(customTemplates);
 
-    static {
-        modesByLabel.put(DATA_MAP_MODE_LABEL, MODE_DATAMAP);
-        modesByLabel.put(ENTITY_MODE_LABEL, MODE_ENTITY);
-        modesByLabel.put(ALL_MODE_LABEL, MODE_ALL);
-    }
+               List<String> superTemplates = new 
ArrayList<String>(templateManager.getStandardSuperclassTemplates());
+               Collections.sort(superTemplates);
+               superTemplates.addAll(customTemplates);
 
-    protected CustomModePanel view;
-    protected CodeTemplateManager templateManager;
+               List<String> subTemplates = new 
ArrayList<String>(templateManager.getStandardSubclassTemplates());
+               Collections.sort(subTemplates);
+               subTemplates.addAll(customTemplates);
 
-    protected ObjectBinding superTemplate;
-    protected ObjectBinding subTemplate;
+               this.view.getSubclassTemplate().setModel(new 
DefaultComboBoxModel(subTemplates.toArray()));
+               this.view.getSuperclassTemplate().setModel(new 
DefaultComboBoxModel(superTemplates.toArray()));
 
-    private CustomPreferencesUpdater preferencesUpdater;
+               superTemplate.updateView();
+               subTemplate.updateView();
+       }
 
-    public CustomPreferencesUpdater getCustomPreferencesUpdater() {
-        return preferencesUpdater;
-    }
+       public Component getView() {
+               return view;
+       }
 
-    public CustomModeController(CodeGeneratorControllerBase parent) {
-        super(parent);
+       public Collection<ClassGenerationAction> createGenerator() {
 
-        Object[] modeChoices = new Object[] {
-                ENTITY_MODE_LABEL, DATA_MAP_MODE_LABEL, ALL_MODE_LABEL
-        };
-        view.getGenerationMode().setModel(new 
DefaultComboBoxModel(modeChoices));
+               mode = 
modesByLabel.get(view.getGenerationMode().getSelectedItem()).toString();
 
-        // bind preferences and init defaults...
+               Collection<ClassGenerationAction> generators = 
super.createGenerator();
 
-        Set<Entry<DataMap, DataMapDefaults>> entities = 
getMapPreferences().entrySet();
+               String superKey = 
view.getSuperclassTemplate().getSelectedItem().toString();
+               String superTemplate = 
templateManager.getTemplatePath(superKey);
 
-        for (Entry<DataMap, DataMapDefaults> entry : entities) {
+               String subKey = 
view.getSubclassTemplate().getSelectedItem().toString();
+               String subTemplate = templateManager.getTemplatePath(subKey);
 
-            if (Util.isEmptyString(entry.getValue().getSuperclassTemplate())) {
-                
entry.getValue().setSuperclassTemplate(CodeTemplateManager.STANDARD_SERVER_SUPERCLASS);
-            }
+               for (ClassGenerationAction generator : generators) {
+                       generator.setSuperTemplate(superTemplate);
+                       generator.setTemplate(subTemplate);
+                       
generator.setOverwrite(view.getOverwrite().isSelected());
+                       
generator.setUsePkgPath(view.getUsePackagePath().isSelected());
+                       generator.setMakePairs(view.getPairs().isSelected());
+                       
generator.setCreatePropertyNames(view.getCreatePropertyNames().isSelected());
 
-            if (Util.isEmptyString(entry.getValue().getSubclassTemplate())) {
-                
entry.getValue().setSubclassTemplate(CodeTemplateManager.STANDARD_SERVER_SUBCLASS);
-            }
-
-            if (Util.isEmptyString(entry.getValue().getProperty("mode"))) {
-                entry.getValue().setProperty("mode", MODE_ENTITY);
-            }
-
-            if (Util.isEmptyString(entry.getValue().getProperty("overwrite"))) 
{
-                entry.getValue().setBooleanProperty("overwrite", false);
-            }
-
-            if (Util.isEmptyString(entry.getValue().getProperty("pairs"))) {
-                entry.getValue().setBooleanProperty("pairs", true);
-            }
-
-            if 
(Util.isEmptyString(entry.getValue().getProperty("usePackagePath"))) {
-                entry.getValue().setBooleanProperty("usePackagePath", true);
-            }
-
-            if 
(Util.isEmptyString(entry.getValue().getProperty("outputPattern"))) {
-                entry.getValue().setProperty("outputPattern", "*.java");
-            }
-        }
-
-        BindingBuilder builder = new BindingBuilder(
-                getApplication().getBindingFactory(),
-                this);
-
-        builder.bindToAction(view.getManageTemplatesLink(), 
"popPreferencesAction()");
-
-        builder.bindToComboSelection(
-                view.getGenerationMode(),
-                "customPreferencesUpdater.mode").
-                updateView();
-
-        builder.bindToStateChange(
-                view.getOverwrite(),
-                "customPreferencesUpdater.overwrite").
-                updateView();
-
-        builder.bindToStateChange(
-                view.getPairs(),
-                "customPreferencesUpdater.pairs").
-                updateView();
-
-        builder.bindToStateChange(
-                view.getUsePackagePath(),
-                "customPreferencesUpdater.usePackagePath").
-                updateView();
-
-        subTemplate = builder.bindToComboSelection(
-                view.getSubclassTemplate(),
-                "customPreferencesUpdater.subclassTemplate");
-
-        superTemplate = builder.bindToComboSelection(
-                view.getSuperclassTemplate(),
-                "customPreferencesUpdater.superclassTemplate");
-
-        builder.bindToTextField(
-                view.getOutputPattern(),
-                "customPreferencesUpdater.outputPattern").
-                updateView();
-
-        builder.bindToStateChange(
-                view.getCreatePropertyNames(),
-                "customPreferencesUpdater.createPropertyNames").
-                updateView();
-
-        updateTemplates();
-    }
-
-    protected void createDefaults() {
-        TreeMap<DataMap, DataMapDefaults> map = new TreeMap<DataMap, 
DataMapDefaults>();
-        Collection<DataMap> dataMaps = getParentController().getDataMaps();
-        for (DataMap dataMap : dataMaps) {
-            DataMapDefaults preferences;
-            preferences = getApplication()
-                    .getFrameController()
-                    .getProjectController()
-                    
.getDataMapPreferences(this.getClass().getName().replace(".", "/"), dataMap);
-            preferences.setSuperclassPackage("");
-            preferences.updateSuperclassPackage(dataMap, false);
-
-            map.put(dataMap, preferences);
-
-            if (getOutputPath() == null) {
-                setOutputPath(preferences.getOutputPath());
-            }
-        }
-
-        setMapPreferences(map);
-        preferencesUpdater = new CustomPreferencesUpdater(map);
-    }
-
-    protected GeneratorControllerPanel createView() {
-        this.view = new CustomModePanel();
-
-        Set<Entry<DataMap, DataMapDefaults>> entities = 
getMapPreferences().entrySet();
-        for (Entry<DataMap, DataMapDefaults> entry : entities) {
-            StandardPanelComponent dataMapLine = 
createDataMapLineBy(entry.getKey(), entry.getValue());
-            
dataMapLine.getDataMapName().setText(dataMapLine.getDataMap().getName());
-            BindingBuilder builder = new 
BindingBuilder(getApplication().getBindingFactory(), dataMapLine);
-            builder.bindToTextField(
-                    dataMapLine.getSuperclassPackage(),
-                    "preferences.superclassPackage").updateView();
-            this.view.addDataMapLine(dataMapLine);
-        }
-        return view;
-    }
-
-    private StandardPanelComponent createDataMapLineBy(DataMap dataMap, 
DataMapDefaults preferences) {
-        StandardPanelComponent dataMapLine = new StandardPanelComponent();
-        dataMapLine.setDataMap(dataMap);
-        dataMapLine.setPreferences(preferences);
-
-        return dataMapLine;
-    }
-
-    protected void updateTemplates() {
-        this.templateManager = getApplication().getCodeTemplateManager();
-
-        List<String> customTemplates = new ArrayList<String>(templateManager
-                .getCustomTemplates()
-                .keySet());
-        Collections.sort(customTemplates);
-
-        List<String> superTemplates = new ArrayList<String>(templateManager
-                .getStandardSuperclassTemplates());
-        Collections.sort(superTemplates);
-        superTemplates.addAll(customTemplates);
-
-        List<String> subTemplates = new ArrayList<String>(templateManager
-                .getStandardSubclassTemplates());
-        Collections.sort(subTemplates);
-        subTemplates.addAll(customTemplates);
-
-        this.view.getSubclassTemplate().setModel(
-                new DefaultComboBoxModel(subTemplates.toArray()));
-        this.view.getSuperclassTemplate().setModel(
-                new DefaultComboBoxModel(superTemplates.toArray()));
-
-        superTemplate.updateView();
-        subTemplate.updateView();
-    }
-
-    public Component getView() {
-        return view;
-    }
-
-    public Collection<ClassGenerationAction> createGenerator() {
-
-        mode = 
modesByLabel.get(view.getGenerationMode().getSelectedItem()).toString();
-
-        Collection<ClassGenerationAction> generators = super.createGenerator();
-
-        String superKey = 
view.getSuperclassTemplate().getSelectedItem().toString();
-        String superTemplate = templateManager.getTemplatePath(superKey);
-
-        String subKey = 
view.getSubclassTemplate().getSelectedItem().toString();
-        String subTemplate = templateManager.getTemplatePath(subKey);
-
-        for (ClassGenerationAction generator : generators) {
-            generator.setSuperTemplate(superTemplate);
-            generator.setTemplate(subTemplate);
-            generator.setOverwrite(view.getOverwrite().isSelected());
-            generator.setUsePkgPath(view.getUsePackagePath().isSelected());
-            generator.setMakePairs(view.getPairs().isSelected());
-            
generator.setCreatePropertyNames(view.getCreatePropertyNames().isSelected());
-
-            if (!Util.isEmptyString(view.getOutputPattern().getText())) {
-                generator.setOutputPattern(view.getOutputPattern().getText());
-            }
-        }
-
-        return generators;
-    }
-
-    public void popPreferencesAction() {
-        new PreferenceDialog(getApplication().getFrameController())
-                .startupAction(PreferenceDialog.TEMPLATES_KEY);
-        updateTemplates();
-    }
-
-    @Override
-    protected ClassGenerationAction newGenerator() {
-        return new ClassGenerationAction();
-    }
+                       if 
(!Util.isEmptyString(view.getOutputPattern().getText())) {
+                               
generator.setOutputPattern(view.getOutputPattern().getText());
+                       }
+               }
+
+               return generators;
+       }
+
+       public void popPreferencesAction() {
+               new 
PreferenceDialog(getApplication().getFrameController()).startupAction(PreferenceDialog.TEMPLATES_KEY);
+               updateTemplates();
+       }
+
+       @Override
+       protected ClassGenerationAction newGenerator() {
+               return new ClassGenerationAction();
+       }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/13d0da53/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/FilterController.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/FilterController.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/FilterController.java
index 2c4ec32..f0dc8b9 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/FilterController.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/FilterController.java
@@ -20,6 +20,7 @@ package org.apache.cayenne.modeler.dialog.datadomain;
 
 import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.Map;
 
 import javax.swing.JTree;
 import javax.swing.tree.TreeNode;
@@ -31,7 +32,7 @@ import org.apache.cayenne.modeler.ProjectTreeView;
 
 public class FilterController {
        
-       private HashMap<String,Boolean> filterMap = new HashMap<String, 
Boolean>();
+       private Map<String,Boolean> filterMap = new HashMap<>();
        private ProjectTreeView tree;
        private ProjectController eventController;
        private ProjectTreeModel treeModel;
@@ -48,7 +49,7 @@ public class FilterController {
                return eventController;
        }
 
-       public HashMap<String, Boolean> getFilterMap() {
+       public Map<String, Boolean> getFilterMap() {
                return filterMap;
        }
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/13d0da53/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datamap/PackageUpdateController.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datamap/PackageUpdateController.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datamap/PackageUpdateController.java
index f1d6a8b..52d2160 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datamap/PackageUpdateController.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datamap/PackageUpdateController.java
@@ -95,7 +95,7 @@ public class PackageUpdateController extends 
DefaultsPreferencesController {
     protected void updatePackage() {
         boolean doAll = isAllEntities();
 
-        Map<String, String> oldNameEmbeddableToNewName = new 
HashMap<String,String>();
+        Map<String, String> oldNameEmbeddableToNewName = new HashMap<>();
         
         for (Embeddable embeddable : dataMap.getEmbeddables()) {
             

http://git-wip-us.apache.org/repos/asf/cayenne/blob/13d0da53/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/TableSelectorController.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/TableSelectorController.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/TableSelectorController.java
index d34dcb7..f9690c2 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/TableSelectorController.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/TableSelectorController.java
@@ -58,9 +58,9 @@ public class TableSelectorController extends 
CayenneController {
     public TableSelectorController(ProjectController parent) {
         super(parent);
         this.view = new TableSelectorView();
-        this.excludedTables = new HashMap<String, DbEntity>();
-        this.selectableTablesList = new ArrayList<DbEntity>();
-        this.validationMessages = new HashMap<String, String>();
+        this.excludedTables = new HashMap<>();
+        this.selectableTablesList = new ArrayList<>();
+        this.validationMessages = new HashMap<>();
         initController();
     }
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/13d0da53/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjAttributeInfoDialog.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjAttributeInfoDialog.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjAttributeInfoDialog.java
index 022ee04..eceaa4f 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjAttributeInfoDialog.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjAttributeInfoDialog.java
@@ -67,750 +67,631 @@ import org.apache.cayenne.modeler.util.ModelerUtil;
 import org.apache.cayenne.swing.BindingBuilder;
 import org.apache.cayenne.util.CayenneMapEntry;
 
-public class ObjAttributeInfoDialog extends CayenneController implements
-        TreeSelectionListener {
-
-    private ObjAttributeTableModel model;
-    private OverrideEmbeddableAttributeTableModel embeddableModel;
-    private int row;
-    protected ObjAttributeInfoDialogView view;
-    protected ObjAttribute attribute;
-    protected ObjAttribute attributeSaved;
-
-    protected List<DbEntity> relTargets;
-
-    protected List<ObjEntity> objectTargets;
-
-    protected Map<String, Embeddable> stringToEmbeddables;
-    protected List<String> embeddableNames;
-
-    protected ProjectController mediator;
-    private Object lastObjectType;
-
-    public ObjAttributeInfoDialog(ProjectController mediator, int row,
-            ObjAttributeTableModel model) {
-        super(mediator);
-        this.view = new ObjAttributeInfoDialogView(mediator);
-        this.mediator = mediator;
-        this.model = model;
-        this.row = row;
-        this.stringToEmbeddables = new HashMap<String, Embeddable>();
-        this.embeddableNames = new ArrayList<String>();
-
-        Iterator<Embeddable> embs = 
mediator.getEmbeddableNamesInCurRentDataDomain().iterator();
-        while (embs.hasNext()) {
-            Embeddable emb = (Embeddable) embs.next();
-            stringToEmbeddables.put(emb.getClassName(), emb);
-            embeddableNames.add(emb.getClassName());
-        }
-        initController(model.getAttribute(row).getValue());
-    }
-
-    @Override
-    public Component getView() {
-        return view;
-    }
-
-    /**
-     * Starts options dialog.
-     */
-    public void startupAction() {
-        view.pack();
-        view.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
-        view.setModal(true);
-        makeCloseableOnEscape();
-        centerView();
-        view.setVisible(true);
-
-    }
-
-    private void initController(ObjAttribute attr) {
-
-        for (int i = 0; i < embeddableNames.size(); i++) {
-            ((DefaultComboBoxModel) 
view.getTypeComboBox().getModel()).addElement(embeddableNames
-                    .get(i)
-                    .toString());
-        }
-
-        this.attribute = attr;
-
-        if (attribute instanceof EmbeddedAttribute
-                || embeddableNames.contains(attribute.getType())) {
-            this.attributeSaved = new EmbeddedAttribute();
-        }
-        else {
-            this.attributeSaved = new ObjAttribute();
-        }
-
-        copyObjAttribute(attributeSaved, attribute);
-
-        relTargets = new ArrayList<DbEntity>(attribute
-                .getEntity()
-                .getDataMap()
-                .getDbEntities());
-
-        /**
-         * Register auto-selection of the target
-         */
-        view.getPathBrowser().addTreeSelectionListener(this);
-
-        view.getAttributeName().setText(attribute.getName());
-        if (attribute.getDbAttributePath() != null) {
-            if (attribute.getDbAttributePath().contains(".")) {
-                String path = attribute.getDbAttributePath();
-                view.getCurrentPathLabel().setText(path.replace(".", " -> "));
-            }
-            else {
-                
view.getCurrentPathLabel().setText(attribute.getDbAttributePath());
-            }
-        }
-        else {
-            view.getCurrentPathLabel().setText("");
-        }
-        view.getSourceEntityLabel().setText(attribute.getEntity().getName());
-
-        view.getTypeComboBox().setSelectedItem(attribute.getType());
-
-        BindingBuilder builder = new BindingBuilder(
-                getApplication().getBindingFactory(),
-                this);
-        builder.bindToAction(view.getCancelButton(), "closeAction()");
-        builder.bindToAction(view.getSelectPathButton(), "setPath(true)");
-        builder.bindToAction(view.getSaveButton(), "saveMapping()");
-
-        /*
-         * set filter for ObjAttributePathBrowser
-         */
-        if (view.getPathBrowser().getModel() == null) {
-            Entity firstEntity = null;
-            if (attribute.getDbAttribute() == null) {
-
-                if (attribute.getParent() instanceof ObjEntity) {
-                    DbEntity dbEnt = ((ObjEntity) 
attribute.getParent()).getDbEntity();
-
-                    if (dbEnt != null) {
-                        Collection<DbAttribute> attrib = dbEnt.getAttributes();
-                        Collection<DbRelationship> rel = 
dbEnt.getRelationships();
-
-                        if (attrib.size() > 0) {
-                            Iterator<DbAttribute> iter = attrib.iterator();
-                            firstEntity = iter.next().getEntity();
-                        }
-                        else if (rel.size() > 0) {
-                            Iterator<DbRelationship> iter = rel.iterator();
-                            firstEntity = iter.next().getSourceEntity();
-                        }
-                    }
-                }
-            }
-            else {
-                firstEntity = getFirstEntity();
-            }
-
-            if (firstEntity != null) {
-                EntityTreeModel treeModel = new EntityTreeModel(firstEntity);
-                treeModel.setFilter(new EntityTreeFilter() {
-
-                    public boolean attributeMatch(Object node, Attribute attr) 
{
-                        if (!(node instanceof Attribute)) {
-                            return true;
-                        }
-                        return false;
-                    }
-
-                    public boolean relationshipMatch(Object node, Relationship 
rel) {
-                        if (!(node instanceof Relationship)) {
-                            return true;
-                        }
-
-                        /**
-                         * We do not allow A->B->A chains, where relationships 
are to-one
-                         */
-                        DbRelationship prev = (DbRelationship) node;
-                        return !(!rel.isToMany() && 
prev.getReverseRelationship() == rel);
-                    }
-                });
-                view.getPathBrowser().setModel(treeModel);
-            }
-        }
-
-        if (attribute.getDbAttribute() != null) {
-            setSelectionPath();
-        }
-
-        view.getTypeComboBox().addItemListener(new ItemListener() {
-
-            public void itemStateChanged(ItemEvent e) {
-                if (lastObjectType != null) {
-                    if (!lastObjectType.equals(e.getItemSelectable())) {
-
-                        if (embeddableNames.contains(e
-                                .getItemSelectable()
-                                .getSelectedObjects()[0].toString())) {
-                            if (attributeSaved instanceof ObjAttribute) {
-                                EmbeddedAttribute copyAttrSaved = new 
EmbeddedAttribute();
-                                copyObjAttribute(copyAttrSaved, 
attributeSaved);
-                                attributeSaved = copyAttrSaved;
-                            }
-                        }
-                        else {
-                            if (attributeSaved instanceof EmbeddedAttribute) {
-                                ObjAttribute copyAttrSaved = new 
ObjAttribute();
-                                copyObjAttribute(copyAttrSaved, 
attributeSaved);
-                                attributeSaved = copyAttrSaved;
-                            }
-                        }
-
-                        attributeSaved
-                                
.setType(e.getItemSelectable().getSelectedObjects()[0]
-                                        .toString());
-                        rebuildTable();
-                        setEnabledSaveButton();
-                    }
-                }
-            }
-        });
-
-        view.getAttributeName().addKeyListener(new KeyListener() {
-
-            public void keyPressed(KeyEvent e) {
-                if 
(!view.getAttributeName().getText().equals(attribute.getName())) {
-                    setEnabledSaveButton();
-                }
-            }
-
-            public void keyReleased(KeyEvent e) {
-                if 
(!view.getAttributeName().getText().equals(attribute.getName())) {
-                    setEnabledSaveButton();
-                }
-            }
-
-            public void keyTyped(KeyEvent e) {
-            }
-        });
-
-        rebuildTable();
-
-    }
-
-    private void setEnabledSaveButton() {
-        if (!attribute.getDbPathIterator().hasNext()) {
-            view.getSaveButton().setEnabled(true);
-        }
-        else {
-            boolean isAttributeLast = false;
-            Iterator<CayenneMapEntry> it = attribute.getDbPathIterator();
-            while (it.hasNext()) {
-                Object obj = it.next();
-                if (obj instanceof DbAttribute && !it.hasNext()) {
-                    isAttributeLast = true;
-                }
-            }
-            view.getSaveButton().setEnabled(isAttributeLast);
-        }
-    }
-
-    private void setUpTableStructure() {
-
-        DefaultTableCellRenderer renderer = new CellRenderer();
-
-        TableColumn nameColumn = view
-                .getOverrideAttributeTable()
-                .getColumnModel()
-                
.getColumn(OverrideEmbeddableAttributeTableModel.OBJ_ATTRIBUTE);
-        nameColumn.setCellRenderer(renderer);
-
-        TableColumn typeColumn = view
-                .getOverrideAttributeTable()
-                .getColumnModel()
-                
.getColumn(OverrideEmbeddableAttributeTableModel.OBJ_ATTRIBUTE_TYPE);
-        typeColumn.setCellRenderer(renderer);
-
-        TableColumn dbAttrColumn = view
-                .getOverrideAttributeTable()
-                .getColumnModel()
-                .getColumn(OverrideEmbeddableAttributeTableModel.DB_ATTRIBUTE);
-        dbAttrColumn.setCellRenderer(renderer);
-
-        TableColumn dbAttrTypeColumn = view
-                .getOverrideAttributeTable()
-                .getColumnModel()
-                
.getColumn(OverrideEmbeddableAttributeTableModel.DB_ATTRIBUTE_TYPE);
-        dbAttrTypeColumn.setCellRenderer(renderer);
-        
-        view.getTablePreferences().bind(
-                view.getOverrideAttributeTable(),
-                null,
-                null,
-                null,
-                OverrideEmbeddableAttributeTableModel.OBJ_ATTRIBUTE,
-                true);
-        
-        initComboBoxes();
-
-    }
-
-    private void initComboBoxes() {
-        Collection<String> nameAttr = null;
-        if (attributeSaved != null) {
-            DbEntity currentEnt = ((ObjEntity) 
attributeSaved.getEntity()).getDbEntity();
-
-            if (currentEnt != null) {
-                nameAttr = ModelerUtil.getDbAttributeNames(mediator, 
currentEnt);
-                embeddableModel.setCellEditor(nameAttr, 
view.getOverrideAttributeTable());
-                embeddableModel.setComboBoxes(
-                        nameAttr,
-                        view.getOverrideAttributeTable().
-                        
convertColumnIndexToView(OverrideEmbeddableAttributeTableModel.DB_ATTRIBUTE));
-            }
-        }
-    }
-
-    private void rebuildTable() {
-        String typeName = null;
-        Collection<EmbeddableAttribute> embAttrTempCopy = new 
ArrayList<EmbeddableAttribute>();
-
-        if (attributeSaved.getType() != null) {
-            typeName = attributeSaved.getType().toString();
-        }
-        if (embeddableNames.contains(typeName)) {
-
-            Collection<EmbeddableAttribute> embAttrTemp = ((Embeddable) 
stringToEmbeddables
-                    .get(typeName)).getAttributes();
-            Iterator<EmbeddableAttribute> it = embAttrTemp.iterator();
-
-            while (it.hasNext()) {
-                EmbeddableAttribute temp = (EmbeddableAttribute) it.next();
-                EmbeddableAttribute at = new EmbeddableAttribute();
-                at.setDbAttributeName(temp.getDbAttributeName());
-                at.setName(temp.getName());
-                at.setType(temp.getType());
-                at.setEmbeddable(temp.getEmbeddable());
-                embAttrTempCopy.add(at);
-            }
-        }
-
-        embeddableModel = new OverrideEmbeddableAttributeTableModel(
-                mediator,
-                this,
-                embAttrTempCopy,
-                attributeSaved);
-
-        view.getOverrideAttributeTable().setModel(embeddableModel);
-        view.getOverrideAttributeTable().setRowHeight(25);
-        view.getOverrideAttributeTable().setRowMargin(3);
-
-        setUpTableStructure();
-
-        if (view.getTypeComboBox().getSelectedItem() == null) {
-            lastObjectType = "";
-        }
-        else {
-            lastObjectType = view.getTypeComboBox().getSelectedItem();
-        }
-    }
-
-    public void closeAction() {
-        view.dispose();
-    }
-
-    public boolean setPath(boolean isChange) {
-
-        if (isChange()) {
-            
attributeSaved.setType(view.getTypeComboBox().getSelectedItem().toString());
-            attributeSaved.setName(view.getAttributeName().getText());
-        }
-
-        if (!(attributeSaved instanceof EmbeddedAttribute)
-                || isRegistredType(attributeSaved.getType())) {
-
-            StringBuilder attributePath = new StringBuilder();
-            StringBuilder pathStr = new StringBuilder();
-            if (((ObjEntity) attribute.getEntity()).getDbEntity() != null) {
-                TreePath path = view.getPathBrowser().getSelectionPath();
-
-                if (path.getLastPathComponent() instanceof DbAttribute) {
-                    Object[] pathComponents = path.getPath();
-                    for (int i = 0; i < pathComponents.length; i++) {
-                        boolean attrOrRel = true;
-                        if (pathComponents[i] instanceof DbAttribute) {
-                            pathStr.append(((DbAttribute) 
pathComponents[i]).getName());
-                            attributePath.append(((DbAttribute) 
pathComponents[i])
-                                    .getName());
-                        }
-                        else if (pathComponents[i] instanceof DbRelationship) {
-                            pathStr
-                                    .append(((DbRelationship) 
pathComponents[i])
-                                            .getName());
-                            attributePath.append(((DbRelationship) 
pathComponents[i])
-                                    .getName());
-                        }
-                        else {
-                            attrOrRel = false;
-                        }
-
-                        if (i != pathComponents.length - 1 && attrOrRel) {
-                            pathStr.append(" -> ");
-                            attributePath.append(".");
-                        }
-                    }
-                }
-            }
-            else {
-                view.getCurrentPathLabel().setText("");
-            }
-
-            view.getCurrentPathLabel().setText(pathStr.toString());
-
-            if (attribute.getDbAttributePath() != null
-                    && !embeddableNames.contains(view
-                            .getTypeComboBox()
-                            .getSelectedItem()
-                            .toString())) {
-                if 
(!attribute.getDbAttributePath().equals(attributePath.toString())) {
-                    
attributeSaved.setDbAttributePath(attributePath.toString());
-
-                    if 
(!attribute.getDbAttributePath().equals(attributePath.toString())
-                            && isChange) {
-                        model.setUpdatedValueAt(
-                                attributeSaved.getDbAttributePath(),
-                                row,
-                                3);
-                    }
-                    return true;
-                }
-            }
-            else {
-                if (attributePath.length() > 0
-                        || (attribute instanceof EmbeddedAttribute && 
!(attributeSaved instanceof EmbeddedAttribute))) {
-
-                    
attributeSaved.setDbAttributePath(attributePath.toString());
-                    if (attributePath.length() == 0) {
-                        model.setUpdatedValueAt(
-                                attributeSaved.getDbAttributePath(),
-                                row,
-                                3);
-                        return false;
-                    }
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    public boolean isChange() {
-
-        boolean isOvverideTableChange = 
((OverrideEmbeddableAttributeTableModel) view
-                .getOverrideAttributeTable()
-                .getModel()).isAttributeOverrideChange();
-        return isOvverideTableChange
-                || 
!attribute.getName().equals(view.getAttributeName().getText())
-                || (attribute.getType() == null && view
-                        .getTypeComboBox()
-                        .getSelectedItem()
-                        .toString() != null)
-                || !attribute.getType().equals(
-                        view.getTypeComboBox().getSelectedItem().toString());
-    }
-
-    public void saveMapping() {
-
-        if (setPath(false)) {
-
-            if (JOptionPane.showConfirmDialog(
-                    (Component) getView(),
-                    "You have changed Db Attribute path. Do you want it to be 
saved?",
-                    "Save ObjAttribute",
-                    JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
-
-                if (attribute instanceof EmbeddedAttribute) {
-                    changeAttributeObject();
-                }
-                else {
-                    model.setUpdatedValueAt(attributeSaved.getName(), row, 1);
-                    model.setUpdatedValueAt(attributeSaved.getType(), row, 2);
-                }
-
-                model.setUpdatedValueAt(attributeSaved.getDbAttributePath(), 
row, 3);
-            }
-            else {
-                model.setUpdatedValueAt(attributeSaved.getName(), row, 1);
-                model.setUpdatedValueAt(attributeSaved.getType(), row, 2);
-            }
-        }
-        else {
-
-            if ((attributeSaved instanceof EmbeddedAttribute && !(attribute 
instanceof EmbeddedAttribute))
-                    || (!(attributeSaved instanceof EmbeddedAttribute) && 
attribute instanceof EmbeddedAttribute)) {
-                changeAttributeObject();
-            }
-            else if ((attributeSaved instanceof EmbeddedAttribute && attribute 
instanceof EmbeddedAttribute)
-                    || (!(attributeSaved instanceof EmbeddedAttribute) && 
!(attribute instanceof EmbeddedAttribute))) {
-
-                if (attributeSaved instanceof EmbeddedAttribute
-                        && embeddableModel.isAttributeOverrideChange()) {
-                    Map<String, String> overrides = ((EmbeddedAttribute) 
attributeSaved)
-                            .getAttributeOverrides();
-                    Map<String, String> currentOverrAttr = 
getCurrentOverrideAttribute();
-
-                    compareAndSetOverrideInEmbeddedAttribute(
-                            attributeSaved,
-                            overrides,
-                            currentOverrAttr);
-                }
-
-                model.setUpdatedValueAt(attributeSaved.getName(), row, 1);
-                model.setUpdatedValueAt(attributeSaved.getType(), row, 2);
-                model.setUpdatedValueAt(attributeSaved.getDbAttributePath(), 
row, 3);
-            }
-
-            if (attributeSaved instanceof EmbeddedAttribute
-                    && attribute instanceof EmbeddedAttribute) {
-
-                model.setUpdatedValueAt(attributeSaved.getDbAttributePath(), 
row, 3);
-                if (embeddableModel.isAttributeOverrideChange()) {
-                    Map<String, String> overrides;
-                    overrides = ((EmbeddedAttribute) 
attribute).getAttributeOverrides();
-                    Map<String, String> currentOverrAttr = 
((EmbeddedAttribute) attributeSaved)
-                            .getAttributeOverrides();
-
-                    compareAndSetOverrideInEmbeddedAttribute(
-                            attribute,
-                            overrides,
-                            currentOverrAttr);
-                }
-            }
-        }
-        closeAction();
-    }
-
-    private void changeAttributeObject() {
-
-        if (attributeSaved instanceof EmbeddedAttribute
-                && embeddableModel.isAttributeOverrideChange()) {
-            Map<String, String> overrides = ((EmbeddedAttribute) 
attributeSaved)
-                    .getAttributeOverrides();
-            Map<String, String> currentOverrAttr = 
getCurrentOverrideAttribute();
-            compareAndSetOverrideInEmbeddedAttribute(
-                    attributeSaved,
-                    overrides,
-                    currentOverrAttr);
-        }
-        if (attributeSaved instanceof EmbeddedAttribute) {
-            attributeSaved.setDbAttributePath(null);
-            model.setUpdatedValueAt(attributeSaved.getDbAttributePath(), row, 
3);
-        }
-
-        model.getEntity().removeAttribute(attribute.getName());
-        model.getEntity().addAttribute(attributeSaved);
-
-        mediator.fireObjEntityEvent(new EntityEvent(
-                this,
-                model.getEntity(),
-                MapEvent.CHANGE));
-
-        EntityDisplayEvent event = new EntityDisplayEvent(this, mediator
-                .getCurrentObjEntity(), mediator.getCurrentDataMap(), 
(DataChannelDescriptor)mediator.getProject().getRootNode());
-
-        mediator.fireObjEntityDisplayEvent(event);
-
-        mediator.fireObjAttributeEvent(new AttributeEvent(this, 
attributeSaved, model
-                .getEntity(), MapEvent.CHANGE));
-
-        AttributeDisplayEvent eventAttr = new AttributeDisplayEvent(
-                this,
-                attributeSaved,
-                mediator.getCurrentObjEntity(),
-                mediator.getCurrentDataMap(),
-                (DataChannelDescriptor)mediator.getProject().getRootNode());
-
-        mediator.fireObjAttributeDisplayEvent(eventAttr);
-
-    }
-
-    public Map<String, String> getCurrentOverrideAttribute() {
-        Map<String, String> currentEmbeddableOverrite = new HashMap<String, 
String>();
-        Collection<EmbeddableAttribute> embList = 
embeddableModel.getEmbeddableList();
-        Embeddable emb = stringToEmbeddables.get(attributeSaved.getType());
-        Iterator<EmbeddableAttribute> it = embList.iterator();
-        while (it.hasNext()) {
-            EmbeddableAttribute e = it.next();
-            if ((emb.getAttribute(e.getName()).getDbAttributeName() == null && 
e
-                    .getDbAttributeName() != null)
-                    || (emb.getAttribute(e.getName()).getDbAttributeName() != 
null && !emb
-                            .getAttribute(e.getName())
-                            .getDbAttributeName()
-                            .equals(e.getDbAttributeName()))) {
-                currentEmbeddableOverrite.put(e.getName(), 
e.getDbAttributeName());
-            }
-        }
-        return currentEmbeddableOverrite;
-    }
-
-    public void valueChanged(TreeSelectionEvent e) {
-    }
-
-    private Entity getFirstEntity() {
-        Iterator<CayenneMapEntry> it = attribute.getDbPathIterator();
-        Entity firstEnt = attribute.getDbAttribute().getEntity();
-        boolean setEnt = false;
-
-        while (it.hasNext()) {
-            Object ob = it.next();
-            if (ob instanceof DbRelationship) {
-                if (!setEnt) {
-                    firstEnt = ((DbRelationship) ob).getSourceEntity();
-                    setEnt = true;
-                }
-            }
-            else if (ob instanceof DbAttribute) {
-                if (!setEnt) {
-                    firstEnt = ((DbAttribute) ob).getEntity();
-                }
-            }
-        }
-
-        return firstEnt;
-    }
-
-    /**
-     * Selects path in browser
-     */
-    public void setSelectionPath() {
-        List list = new ArrayList();
-        boolean isAttributeLast = false;
-        Iterator<CayenneMapEntry> it = attribute.getDbPathIterator();
-        while (it.hasNext()) {
-            Object obj = it.next();
-            list.add(obj);
-            if (obj instanceof DbAttribute && !it.hasNext()) {
-                isAttributeLast = true;
-            }
-        }
-        if (isAttributeLast) {
-            Object[] path = new Object[list.size() + 1];
-            path[0] = getFirstEntity();
-            System.arraycopy(list.toArray(), 0, path, 1, list.size());
-            view.getPathBrowser().setSelectionPath(new TreePath(path));
-            view.getSaveButton().setEnabled(true);
-        }
-    }
-
-    public boolean isRegistredType(String typeName) {
-        boolean isType = false;
-        String[] typeNames = ModelerUtil.getRegisteredTypeNames();
-        for (int i = 0; i < typeNames.length; i++) {
-            if (typeNames[i].equals(typeName)) {
-                isType = true;
-            }
-        }
-        return isType;
-    }
-
-    // custom renderer used for inherited attributes highlighting
-    final class CellRenderer extends DefaultTableCellRenderer {
-
-        @Override
-        public Component getTableCellRendererComponent(
-                JTable table,
-                Object value,
-                boolean isSelected,
-                boolean hasFocus,
-                int row,
-                int column) {
-
-            super.getTableCellRendererComponent(
-                    table,
-                    value,
-                    isSelected,
-                    hasFocus,
-                    row,
-                    column);
-
-            OverrideEmbeddableAttributeTableModel model = 
(OverrideEmbeddableAttributeTableModel) table
-                    .getModel();
-
-            if (!model.isCellEditable(row, column)) {
-                setForeground(Color.GRAY);
-            }
-            else {
-                setForeground(isSelected && !hasFocus
-                        ? table.getSelectionForeground()
-                        : table.getForeground());
-            }
-            setBackground(isSelected && !hasFocus
-                    ? table.getSelectionBackground()
-                    : table.getBackground());
-
-            return this;
-        }
-    }
-
-    private void copyObjAttribute(ObjAttribute attributeSaved, ObjAttribute 
attribute) {
-        attributeSaved.setDbAttributePath(attribute.getDbAttributePath());
-        attributeSaved.setName(attribute.getName());
-        attributeSaved.setEntity(attribute.getEntity());
-        attributeSaved.setParent(attribute.getParent());
-        attributeSaved.setType(attribute.getType());
-        attributeSaved.setUsedForLocking(attribute.isUsedForLocking());
-
-        if (attributeSaved instanceof EmbeddedAttribute) {
-            Map<String, String> attrOverrides;
-            if (attribute instanceof EmbeddedAttribute) {
-                attrOverrides = ((EmbeddedAttribute) 
attribute).getAttributeOverrides();
-            }
-            else {
-                attrOverrides = new HashMap<String, String>();
-            }
-            if (attrOverrides.size() > 0) {
-                Iterator it = attrOverrides.entrySet().iterator();
-
-                while (it.hasNext()) {
-                    Map.Entry attrOv = (Map.Entry) it.next();
-                    ((EmbeddedAttribute) 
attributeSaved).addAttributeOverride(attrOv
-                            .getKey()
-                            .toString(), attrOv.getValue().toString());
-                }
-            }
-        }
-    }
-
-    private void compareAndSetOverrideInEmbeddedAttribute(
-            ObjAttribute attribute,
-            Map<String, String> overrides,
-            Map<String, String> currentOverrAttr) {
-        ArrayList<String> keysForDelete = new ArrayList<String>();
-        ArrayList<String> keysForAdd = new ArrayList<String>();
-
-        Iterator it = overrides.entrySet().iterator();
-        while (it.hasNext()) {
-            Map.Entry obj = (Map.Entry) it.next();
-
-            String key = (String) obj.getKey();
-            if (currentOverrAttr.get(key) == null
-                    || !(obj.getValue().equals(currentOverrAttr.get(key)))) {
-                keysForDelete.add(key);
-            }
-        }
-
-        Iterator iter = currentOverrAttr.entrySet().iterator();
-        while (iter.hasNext()) {
-            Map.Entry obj = (Map.Entry) iter.next();
-            String key = (String) obj.getKey();
-            if (overrides.get(key) == null
-                    || !(obj.getValue().equals(overrides.get(key)))) {
-                keysForAdd.add(key);
-            }
-        }
-
-        for (int i = 0; i < keysForDelete.size(); i++) {
-            ((EmbeddedAttribute) 
attribute).removeAttributeOverride(keysForDelete.get(i));
-        }
-        for (int i = 0; i < keysForAdd.size(); i++) {
-            String key = keysForAdd.get(i);
-            ((EmbeddedAttribute) attribute).addAttributeOverride(key, 
currentOverrAttr
-                    .get(key));
-        }
-    }
+public class ObjAttributeInfoDialog extends CayenneController implements 
TreeSelectionListener {
+
+       private ObjAttributeTableModel model;
+       private OverrideEmbeddableAttributeTableModel embeddableModel;
+       private int row;
+       protected ObjAttributeInfoDialogView view;
+       protected ObjAttribute attribute;
+       protected ObjAttribute attributeSaved;
+
+       protected List<DbEntity> relTargets;
+
+       protected List<ObjEntity> objectTargets;
+
+       protected Map<String, Embeddable> stringToEmbeddables;
+       protected List<String> embeddableNames;
+
+       protected ProjectController mediator;
+       private Object lastObjectType;
+
+       public ObjAttributeInfoDialog(ProjectController mediator, int row, 
ObjAttributeTableModel model) {
+               super(mediator);
+               this.view = new ObjAttributeInfoDialogView(mediator);
+               this.mediator = mediator;
+               this.model = model;
+               this.row = row;
+               this.stringToEmbeddables = new HashMap<>();
+               this.embeddableNames = new ArrayList<String>();
+
+               Iterator<Embeddable> embs = 
mediator.getEmbeddableNamesInCurRentDataDomain().iterator();
+               while (embs.hasNext()) {
+                       Embeddable emb = (Embeddable) embs.next();
+                       stringToEmbeddables.put(emb.getClassName(), emb);
+                       embeddableNames.add(emb.getClassName());
+               }
+               initController(model.getAttribute(row).getValue());
+       }
+
+       @Override
+       public Component getView() {
+               return view;
+       }
+
+       /**
+        * Starts options dialog.
+        */
+       public void startupAction() {
+               view.pack();
+               view.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+               view.setModal(true);
+               makeCloseableOnEscape();
+               centerView();
+               view.setVisible(true);
+
+       }
+
+       private void initController(ObjAttribute attr) {
+
+               for (int i = 0; i < embeddableNames.size(); i++) {
+                       ((DefaultComboBoxModel) 
view.getTypeComboBox().getModel()).addElement(embeddableNames.get(i).toString());
+               }
+
+               this.attribute = attr;
+
+               if (attribute instanceof EmbeddedAttribute || 
embeddableNames.contains(attribute.getType())) {
+                       this.attributeSaved = new EmbeddedAttribute();
+               } else {
+                       this.attributeSaved = new ObjAttribute();
+               }
+
+               copyObjAttribute(attributeSaved, attribute);
+
+               relTargets = new 
ArrayList<DbEntity>(attribute.getEntity().getDataMap().getDbEntities());
+
+               /**
+                * Register auto-selection of the target
+                */
+               view.getPathBrowser().addTreeSelectionListener(this);
+
+               view.getAttributeName().setText(attribute.getName());
+               if (attribute.getDbAttributePath() != null) {
+                       if (attribute.getDbAttributePath().contains(".")) {
+                               String path = attribute.getDbAttributePath();
+                               
view.getCurrentPathLabel().setText(path.replace(".", " -> "));
+                       } else {
+                               
view.getCurrentPathLabel().setText(attribute.getDbAttributePath());
+                       }
+               } else {
+                       view.getCurrentPathLabel().setText("");
+               }
+               
view.getSourceEntityLabel().setText(attribute.getEntity().getName());
+
+               view.getTypeComboBox().setSelectedItem(attribute.getType());
+
+               BindingBuilder builder = new 
BindingBuilder(getApplication().getBindingFactory(), this);
+               builder.bindToAction(view.getCancelButton(), "closeAction()");
+               builder.bindToAction(view.getSelectPathButton(), 
"setPath(true)");
+               builder.bindToAction(view.getSaveButton(), "saveMapping()");
+
+               /*
+                * set filter for ObjAttributePathBrowser
+                */
+               if (view.getPathBrowser().getModel() == null) {
+                       Entity firstEntity = null;
+                       if (attribute.getDbAttribute() == null) {
+
+                               if (attribute.getParent() instanceof ObjEntity) 
{
+                                       DbEntity dbEnt = ((ObjEntity) 
attribute.getParent()).getDbEntity();
+
+                                       if (dbEnt != null) {
+                                               Collection<DbAttribute> attrib 
= dbEnt.getAttributes();
+                                               Collection<DbRelationship> rel 
= dbEnt.getRelationships();
+
+                                               if (attrib.size() > 0) {
+                                                       Iterator<DbAttribute> 
iter = attrib.iterator();
+                                                       firstEntity = 
iter.next().getEntity();
+                                               } else if (rel.size() > 0) {
+                                                       
Iterator<DbRelationship> iter = rel.iterator();
+                                                       firstEntity = 
iter.next().getSourceEntity();
+                                               }
+                                       }
+                               }
+                       } else {
+                               firstEntity = getFirstEntity();
+                       }
+
+                       if (firstEntity != null) {
+                               EntityTreeModel treeModel = new 
EntityTreeModel(firstEntity);
+                               treeModel.setFilter(new EntityTreeFilter() {
+
+                                       public boolean attributeMatch(Object 
node, Attribute attr) {
+                                               if (!(node instanceof 
Attribute)) {
+                                                       return true;
+                                               }
+                                               return false;
+                                       }
+
+                                       public boolean relationshipMatch(Object 
node, Relationship rel) {
+                                               if (!(node instanceof 
Relationship)) {
+                                                       return true;
+                                               }
+
+                                               /**
+                                                * We do not allow A->B->A 
chains, where relationships
+                                                * are to-one
+                                                */
+                                               DbRelationship prev = 
(DbRelationship) node;
+                                               return !(!rel.isToMany() && 
prev.getReverseRelationship() == rel);
+                                       }
+                               });
+                               view.getPathBrowser().setModel(treeModel);
+                       }
+               }
+
+               if (attribute.getDbAttribute() != null) {
+                       setSelectionPath();
+               }
+
+               view.getTypeComboBox().addItemListener(new ItemListener() {
+
+                       public void itemStateChanged(ItemEvent e) {
+                               if (lastObjectType != null) {
+                                       if 
(!lastObjectType.equals(e.getItemSelectable())) {
+
+                                               if 
(embeddableNames.contains(e.getItemSelectable().getSelectedObjects()[0].toString()))
 {
+                                                       if (attributeSaved 
instanceof ObjAttribute) {
+                                                               
EmbeddedAttribute copyAttrSaved = new EmbeddedAttribute();
+                                                               
copyObjAttribute(copyAttrSaved, attributeSaved);
+                                                               attributeSaved 
= copyAttrSaved;
+                                                       }
+                                               } else {
+                                                       if (attributeSaved 
instanceof EmbeddedAttribute) {
+                                                               ObjAttribute 
copyAttrSaved = new ObjAttribute();
+                                                               
copyObjAttribute(copyAttrSaved, attributeSaved);
+                                                               attributeSaved 
= copyAttrSaved;
+                                                       }
+                                               }
+
+                                               
attributeSaved.setType(e.getItemSelectable().getSelectedObjects()[0].toString());
+                                               rebuildTable();
+                                               setEnabledSaveButton();
+                                       }
+                               }
+                       }
+               });
+
+               view.getAttributeName().addKeyListener(new KeyListener() {
+
+                       public void keyPressed(KeyEvent e) {
+                               if 
(!view.getAttributeName().getText().equals(attribute.getName())) {
+                                       setEnabledSaveButton();
+                               }
+                       }
+
+                       public void keyReleased(KeyEvent e) {
+                               if 
(!view.getAttributeName().getText().equals(attribute.getName())) {
+                                       setEnabledSaveButton();
+                               }
+                       }
+
+                       public void keyTyped(KeyEvent e) {
+                       }
+               });
+
+               rebuildTable();
+
+       }
+
+       private void setEnabledSaveButton() {
+               if (!attribute.getDbPathIterator().hasNext()) {
+                       view.getSaveButton().setEnabled(true);
+               } else {
+                       boolean isAttributeLast = false;
+                       Iterator<CayenneMapEntry> it = 
attribute.getDbPathIterator();
+                       while (it.hasNext()) {
+                               Object obj = it.next();
+                               if (obj instanceof DbAttribute && 
!it.hasNext()) {
+                                       isAttributeLast = true;
+                               }
+                       }
+                       view.getSaveButton().setEnabled(isAttributeLast);
+               }
+       }
+
+       private void setUpTableStructure() {
+
+               DefaultTableCellRenderer renderer = new CellRenderer();
+
+               TableColumn nameColumn = 
view.getOverrideAttributeTable().getColumnModel()
+                               
.getColumn(OverrideEmbeddableAttributeTableModel.OBJ_ATTRIBUTE);
+               nameColumn.setCellRenderer(renderer);
+
+               TableColumn typeColumn = 
view.getOverrideAttributeTable().getColumnModel()
+                               
.getColumn(OverrideEmbeddableAttributeTableModel.OBJ_ATTRIBUTE_TYPE);
+               typeColumn.setCellRenderer(renderer);
+
+               TableColumn dbAttrColumn = 
view.getOverrideAttributeTable().getColumnModel()
+                               
.getColumn(OverrideEmbeddableAttributeTableModel.DB_ATTRIBUTE);
+               dbAttrColumn.setCellRenderer(renderer);
+
+               TableColumn dbAttrTypeColumn = 
view.getOverrideAttributeTable().getColumnModel()
+                               
.getColumn(OverrideEmbeddableAttributeTableModel.DB_ATTRIBUTE_TYPE);
+               dbAttrTypeColumn.setCellRenderer(renderer);
+
+               
view.getTablePreferences().bind(view.getOverrideAttributeTable(), null, null, 
null,
+                               
OverrideEmbeddableAttributeTableModel.OBJ_ATTRIBUTE, true);
+
+               initComboBoxes();
+
+       }
+
+       private void initComboBoxes() {
+               Collection<String> nameAttr = null;
+               if (attributeSaved != null) {
+                       DbEntity currentEnt = ((ObjEntity) 
attributeSaved.getEntity()).getDbEntity();
+
+                       if (currentEnt != null) {
+                               nameAttr = 
ModelerUtil.getDbAttributeNames(mediator, currentEnt);
+                               embeddableModel.setCellEditor(nameAttr, 
view.getOverrideAttributeTable());
+                               embeddableModel.setComboBoxes(
+                                               nameAttr,
+                                               
view.getOverrideAttributeTable().convertColumnIndexToView(
+                                                               
OverrideEmbeddableAttributeTableModel.DB_ATTRIBUTE));
+                       }
+               }
+       }
+
+       private void rebuildTable() {
+               String typeName = null;
+               Collection<EmbeddableAttribute> embAttrTempCopy = new 
ArrayList<EmbeddableAttribute>();
+
+               if (attributeSaved.getType() != null) {
+                       typeName = attributeSaved.getType().toString();
+               }
+               if (embeddableNames.contains(typeName)) {
+
+                       Collection<EmbeddableAttribute> embAttrTemp = 
((Embeddable) stringToEmbeddables.get(typeName))
+                                       .getAttributes();
+                       Iterator<EmbeddableAttribute> it = 
embAttrTemp.iterator();
+
+                       while (it.hasNext()) {
+                               EmbeddableAttribute temp = 
(EmbeddableAttribute) it.next();
+                               EmbeddableAttribute at = new 
EmbeddableAttribute();
+                               
at.setDbAttributeName(temp.getDbAttributeName());
+                               at.setName(temp.getName());
+                               at.setType(temp.getType());
+                               at.setEmbeddable(temp.getEmbeddable());
+                               embAttrTempCopy.add(at);
+                       }
+               }
+
+               embeddableModel = new 
OverrideEmbeddableAttributeTableModel(mediator, this, embAttrTempCopy, 
attributeSaved);
+
+               view.getOverrideAttributeTable().setModel(embeddableModel);
+               view.getOverrideAttributeTable().setRowHeight(25);
+               view.getOverrideAttributeTable().setRowMargin(3);
+
+               setUpTableStructure();
+
+               if (view.getTypeComboBox().getSelectedItem() == null) {
+                       lastObjectType = "";
+               } else {
+                       lastObjectType = 
view.getTypeComboBox().getSelectedItem();
+               }
+       }
+
+       public void closeAction() {
+               view.dispose();
+       }
+
+       public boolean setPath(boolean isChange) {
+
+               if (isChange()) {
+                       
attributeSaved.setType(view.getTypeComboBox().getSelectedItem().toString());
+                       
attributeSaved.setName(view.getAttributeName().getText());
+               }
+
+               if (!(attributeSaved instanceof EmbeddedAttribute) || 
isRegistredType(attributeSaved.getType())) {
+
+                       StringBuilder attributePath = new StringBuilder();
+                       StringBuilder pathStr = new StringBuilder();
+                       if (((ObjEntity) attribute.getEntity()).getDbEntity() 
!= null) {
+                               TreePath path = 
view.getPathBrowser().getSelectionPath();
+
+                               if (path.getLastPathComponent() instanceof 
DbAttribute) {
+                                       Object[] pathComponents = 
path.getPath();
+                                       for (int i = 0; i < 
pathComponents.length; i++) {
+                                               boolean attrOrRel = true;
+                                               if (pathComponents[i] 
instanceof DbAttribute) {
+                                                       
pathStr.append(((DbAttribute) pathComponents[i]).getName());
+                                                       
attributePath.append(((DbAttribute) pathComponents[i]).getName());
+                                               } else if (pathComponents[i] 
instanceof DbRelationship) {
+                                                       
pathStr.append(((DbRelationship) pathComponents[i]).getName());
+                                                       
attributePath.append(((DbRelationship) pathComponents[i]).getName());
+                                               } else {
+                                                       attrOrRel = false;
+                                               }
+
+                                               if (i != pathComponents.length 
- 1 && attrOrRel) {
+                                                       pathStr.append(" -> ");
+                                                       
attributePath.append(".");
+                                               }
+                                       }
+                               }
+                       } else {
+                               view.getCurrentPathLabel().setText("");
+                       }
+
+                       view.getCurrentPathLabel().setText(pathStr.toString());
+
+                       if (attribute.getDbAttributePath() != null
+                                       && 
!embeddableNames.contains(view.getTypeComboBox().getSelectedItem().toString())) 
{
+                               if 
(!attribute.getDbAttributePath().equals(attributePath.toString())) {
+                                       
attributeSaved.setDbAttributePath(attributePath.toString());
+
+                                       if 
(!attribute.getDbAttributePath().equals(attributePath.toString()) && isChange) {
+                                               
model.setUpdatedValueAt(attributeSaved.getDbAttributePath(), row, 3);
+                                       }
+                                       return true;
+                               }
+                       } else {
+                               if (attributePath.length() > 0
+                                               || (attribute instanceof 
EmbeddedAttribute && !(attributeSaved instanceof EmbeddedAttribute))) {
+
+                                       
attributeSaved.setDbAttributePath(attributePath.toString());
+                                       if (attributePath.length() == 0) {
+                                               
model.setUpdatedValueAt(attributeSaved.getDbAttributePath(), row, 3);
+                                               return false;
+                                       }
+                                       return true;
+                               }
+                       }
+               }
+               return false;
+       }
+
+       public boolean isChange() {
+
+               boolean isOvverideTableChange = 
((OverrideEmbeddableAttributeTableModel) view.getOverrideAttributeTable()
+                               .getModel()).isAttributeOverrideChange();
+               return isOvverideTableChange || 
!attribute.getName().equals(view.getAttributeName().getText())
+                               || (attribute.getType() == null && 
view.getTypeComboBox().getSelectedItem().toString() != null)
+                               || 
!attribute.getType().equals(view.getTypeComboBox().getSelectedItem().toString());
+       }
+
+       public void saveMapping() {
+
+               if (setPath(false)) {
+
+                       if (JOptionPane.showConfirmDialog((Component) getView(),
+                                       "You have changed Db Attribute path. Do 
you want it to be saved?", "Save ObjAttribute",
+                                       JOptionPane.YES_NO_OPTION) == 
JOptionPane.YES_OPTION) {
+
+                               if (attribute instanceof EmbeddedAttribute) {
+                                       changeAttributeObject();
+                               } else {
+                                       
model.setUpdatedValueAt(attributeSaved.getName(), row, 1);
+                                       
model.setUpdatedValueAt(attributeSaved.getType(), row, 2);
+                               }
+
+                               
model.setUpdatedValueAt(attributeSaved.getDbAttributePath(), row, 3);
+                       } else {
+                               
model.setUpdatedValueAt(attributeSaved.getName(), row, 1);
+                               
model.setUpdatedValueAt(attributeSaved.getType(), row, 2);
+                       }
+               } else {
+
+                       if ((attributeSaved instanceof EmbeddedAttribute && 
!(attribute instanceof EmbeddedAttribute))
+                                       || (!(attributeSaved instanceof 
EmbeddedAttribute) && attribute instanceof EmbeddedAttribute)) {
+                               changeAttributeObject();
+                       } else if ((attributeSaved instanceof EmbeddedAttribute 
&& attribute instanceof EmbeddedAttribute)
+                                       || (!(attributeSaved instanceof 
EmbeddedAttribute) && !(attribute instanceof EmbeddedAttribute))) {
+
+                               if (attributeSaved instanceof EmbeddedAttribute 
&& embeddableModel.isAttributeOverrideChange()) {
+                                       Map<String, String> overrides = 
((EmbeddedAttribute) attributeSaved).getAttributeOverrides();
+                                       Map<String, String> currentOverrAttr = 
getCurrentOverrideAttribute();
+
+                                       
compareAndSetOverrideInEmbeddedAttribute(attributeSaved, overrides, 
currentOverrAttr);
+                               }
+
+                               
model.setUpdatedValueAt(attributeSaved.getName(), row, 1);
+                               
model.setUpdatedValueAt(attributeSaved.getType(), row, 2);
+                               
model.setUpdatedValueAt(attributeSaved.getDbAttributePath(), row, 3);
+                       }
+
+                       if (attributeSaved instanceof EmbeddedAttribute && 
attribute instanceof EmbeddedAttribute) {
+
+                               
model.setUpdatedValueAt(attributeSaved.getDbAttributePath(), row, 3);
+                               if 
(embeddableModel.isAttributeOverrideChange()) {
+                                       Map<String, String> overrides;
+                                       overrides = ((EmbeddedAttribute) 
attribute).getAttributeOverrides();
+                                       Map<String, String> currentOverrAttr = 
((EmbeddedAttribute) attributeSaved).getAttributeOverrides();
+
+                                       
compareAndSetOverrideInEmbeddedAttribute(attribute, overrides, 
currentOverrAttr);
+                               }
+                       }
+               }
+               closeAction();
+       }
+
+       private void changeAttributeObject() {
+
+               if (attributeSaved instanceof EmbeddedAttribute && 
embeddableModel.isAttributeOverrideChange()) {
+                       Map<String, String> overrides = ((EmbeddedAttribute) 
attributeSaved).getAttributeOverrides();
+                       Map<String, String> currentOverrAttr = 
getCurrentOverrideAttribute();
+                       
compareAndSetOverrideInEmbeddedAttribute(attributeSaved, overrides, 
currentOverrAttr);
+               }
+               if (attributeSaved instanceof EmbeddedAttribute) {
+                       attributeSaved.setDbAttributePath(null);
+                       
model.setUpdatedValueAt(attributeSaved.getDbAttributePath(), row, 3);
+               }
+
+               model.getEntity().removeAttribute(attribute.getName());
+               model.getEntity().addAttribute(attributeSaved);
+
+               mediator.fireObjEntityEvent(new EntityEvent(this, 
model.getEntity(), MapEvent.CHANGE));
+
+               EntityDisplayEvent event = new EntityDisplayEvent(this, 
mediator.getCurrentObjEntity(),
+                               mediator.getCurrentDataMap(), 
(DataChannelDescriptor) mediator.getProject().getRootNode());
+
+               mediator.fireObjEntityDisplayEvent(event);
+
+               mediator.fireObjAttributeEvent(new AttributeEvent(this, 
attributeSaved, model.getEntity(), MapEvent.CHANGE));
+
+               AttributeDisplayEvent eventAttr = new 
AttributeDisplayEvent(this, attributeSaved,
+                               mediator.getCurrentObjEntity(), 
mediator.getCurrentDataMap(), (DataChannelDescriptor) mediator
+                                               .getProject().getRootNode());
+
+               mediator.fireObjAttributeDisplayEvent(eventAttr);
+
+       }
+
+       public Map<String, String> getCurrentOverrideAttribute() {
+               Map<String, String> currentEmbeddableOverrite = new HashMap<>();
+               Collection<EmbeddableAttribute> embList = 
embeddableModel.getEmbeddableList();
+               Embeddable emb = 
stringToEmbeddables.get(attributeSaved.getType());
+               Iterator<EmbeddableAttribute> it = embList.iterator();
+               while (it.hasNext()) {
+                       EmbeddableAttribute e = it.next();
+                       if ((emb.getAttribute(e.getName()).getDbAttributeName() 
== null && e.getDbAttributeName() != null)
+                                       || 
(emb.getAttribute(e.getName()).getDbAttributeName() != null && 
!emb.getAttribute(e.getName())
+                                                       
.getDbAttributeName().equals(e.getDbAttributeName()))) {
+                               currentEmbeddableOverrite.put(e.getName(), 
e.getDbAttributeName());
+                       }
+               }
+               return currentEmbeddableOverrite;
+       }
+
+       public void valueChanged(TreeSelectionEvent e) {
+       }
+
+       private Entity getFirstEntity() {
+               Iterator<CayenneMapEntry> it = attribute.getDbPathIterator();
+               Entity firstEnt = attribute.getDbAttribute().getEntity();
+               boolean setEnt = false;
+
+               while (it.hasNext()) {
+                       Object ob = it.next();
+                       if (ob instanceof DbRelationship) {
+                               if (!setEnt) {
+                                       firstEnt = ((DbRelationship) 
ob).getSourceEntity();
+                                       setEnt = true;
+                               }
+                       } else if (ob instanceof DbAttribute) {
+                               if (!setEnt) {
+                                       firstEnt = ((DbAttribute) 
ob).getEntity();
+                               }
+                       }
+               }
+
+               return firstEnt;
+       }
+
+       /**
+        * Selects path in browser
+        */
+       public void setSelectionPath() {
+               List list = new ArrayList();
+               boolean isAttributeLast = false;
+               Iterator<CayenneMapEntry> it = attribute.getDbPathIterator();
+               while (it.hasNext()) {
+                       Object obj = it.next();
+                       list.add(obj);
+                       if (obj instanceof DbAttribute && !it.hasNext()) {
+                               isAttributeLast = true;
+                       }
+               }
+               if (isAttributeLast) {
+                       Object[] path = new Object[list.size() + 1];
+                       path[0] = getFirstEntity();
+                       System.arraycopy(list.toArray(), 0, path, 1, 
list.size());
+                       view.getPathBrowser().setSelectionPath(new 
TreePath(path));
+                       view.getSaveButton().setEnabled(true);
+               }
+       }
+
+       public boolean isRegistredType(String typeName) {
+               boolean isType = false;
+               String[] typeNames = ModelerUtil.getRegisteredTypeNames();
+               for (int i = 0; i < typeNames.length; i++) {
+                       if (typeNames[i].equals(typeName)) {
+                               isType = true;
+                       }
+               }
+               return isType;
+       }
+
+       // custom renderer used for inherited attributes highlighting
+       final class CellRenderer extends DefaultTableCellRenderer {
+
+               @Override
+               public Component getTableCellRendererComponent(JTable table, 
Object value, boolean isSelected,
+                               boolean hasFocus, int row, int column) {
+
+                       super.getTableCellRendererComponent(table, value, 
isSelected, hasFocus, row, column);
+
+                       OverrideEmbeddableAttributeTableModel model = 
(OverrideEmbeddableAttributeTableModel) table.getModel();
+
+                       if (!model.isCellEditable(row, column)) {
+                               setForeground(Color.GRAY);
+                       } else {
+                               setForeground(isSelected && !hasFocus ? 
table.getSelectionForeground() : table.getForeground());
+                       }
+                       setBackground(isSelected && !hasFocus ? 
table.getSelectionBackground() : table.getBackground());
+
+                       return this;
+               }
+       }
+
+       private void copyObjAttribute(ObjAttribute attributeSaved, ObjAttribute 
attribute) {
+               
attributeSaved.setDbAttributePath(attribute.getDbAttributePath());
+               attributeSaved.setName(attribute.getName());
+               attributeSaved.setEntity(attribute.getEntity());
+               attributeSaved.setParent(attribute.getParent());
+               attributeSaved.setType(attribute.getType());
+               attributeSaved.setUsedForLocking(attribute.isUsedForLocking());
+
+               if (attributeSaved instanceof EmbeddedAttribute) {
+                       Map<String, String> attrOverrides;
+                       if (attribute instanceof EmbeddedAttribute) {
+                               attrOverrides = ((EmbeddedAttribute) 
attribute).getAttributeOverrides();
+                       } else {
+                               attrOverrides = new HashMap<>();
+                       }
+                       if (attrOverrides.size() > 0) {
+                               Iterator it = 
attrOverrides.entrySet().iterator();
+
+                               while (it.hasNext()) {
+                                       Map.Entry attrOv = (Map.Entry) 
it.next();
+                                       ((EmbeddedAttribute) 
attributeSaved).addAttributeOverride(attrOv.getKey().toString(), attrOv
+                                                       .getValue().toString());
+                               }
+                       }
+               }
+       }
+
+       private void compareAndSetOverrideInEmbeddedAttribute(ObjAttribute 
attribute, Map<String, String> overrides,
+                       Map<String, String> currentOverrAttr) {
+               ArrayList<String> keysForDelete = new ArrayList<String>();
+               ArrayList<String> keysForAdd = new ArrayList<String>();
+
+               Iterator it = overrides.entrySet().iterator();
+               while (it.hasNext()) {
+                       Map.Entry obj = (Map.Entry) it.next();
+
+                       String key = (String) obj.getKey();
+                       if (currentOverrAttr.get(key) == null || 
!(obj.getValue().equals(currentOverrAttr.get(key)))) {
+                               keysForDelete.add(key);
+                       }
+               }
+
+               Iterator iter = currentOverrAttr.entrySet().iterator();
+               while (iter.hasNext()) {
+                       Map.Entry obj = (Map.Entry) iter.next();
+                       String key = (String) obj.getKey();
+                       if (overrides.get(key) == null || 
!(obj.getValue().equals(overrides.get(key)))) {
+                               keysForAdd.add(key);
+                       }
+               }
+
+               for (int i = 0; i < keysForDelete.size(); i++) {
+                       ((EmbeddedAttribute) 
attribute).removeAttributeOverride(keysForDelete.get(i));
+               }
+               for (int i = 0; i < keysForAdd.size(); i++) {
+                       String key = keysForAdd.get(i);
+                       ((EmbeddedAttribute) 
attribute).addAttributeOverride(key, currentOverrAttr.get(key));
+               }
+       }
 }

Reply via email to