http://git-wip-us.apache.org/repos/asf/cayenne/blob/51289d1c/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/TreeManipulationAction.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/TreeManipulationAction.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/TreeManipulationAction.java
deleted file mode 100644
index 6b38f34..0000000
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/TreeManipulationAction.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.modeler.action;
-
-import org.apache.cayenne.dbsync.reverse.dbimport.Catalog;
-import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeColumn;
-import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeProcedure;
-import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeTable;
-import org.apache.cayenne.dbsync.reverse.dbimport.IncludeColumn;
-import org.apache.cayenne.dbsync.reverse.dbimport.IncludeProcedure;
-import org.apache.cayenne.dbsync.reverse.dbimport.IncludeTable;
-import org.apache.cayenne.dbsync.reverse.dbimport.ReverseEngineering;
-import org.apache.cayenne.dbsync.reverse.dbimport.Schema;
-import org.apache.cayenne.modeler.Application;
-import org.apache.cayenne.modeler.dialog.db.load.DbImportTreeNode;
-import org.apache.cayenne.modeler.editor.DbImportModel;
-import org.apache.cayenne.modeler.editor.DbImportTree;
-import org.apache.cayenne.modeler.util.CayenneAction;
-
-import javax.swing.JTree;
-import javax.swing.tree.TreePath;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @since 4.1
- */
-public abstract class TreeManipulationAction extends CayenneAction {
-
-    static final String EMPTY_NAME = "";
-
-    protected DbImportTree tree;
-    protected DbImportTreeNode selectedElement;
-    DbImportTreeNode parentElement;
-    DbImportTreeNode foundNode;
-    String insertableNodeName;
-    Class insertableNodeClass;
-    boolean isMultipleAction;
-    private boolean movedFromDbSchema;
-    private Map<Class, List<Class>> levels;
-
-    public TreeManipulationAction(String name, Application application) {
-        super(name, application);
-        initLevels();
-    }
-
-    boolean reverseEngineeringIsEmpty() {
-        ReverseEngineering reverseEngineering = tree.getReverseEngineering();
-        return ((reverseEngineering.getCatalogs().size() == 0) && 
(reverseEngineering.getSchemas().size() == 0)
-                && (reverseEngineering.getIncludeTables().size() == 0) && 
(reverseEngineering.getExcludeTables().size() == 0)
-                && (reverseEngineering.getIncludeColumns().size() == 0) && 
(reverseEngineering.getExcludeColumns().size() == 0)
-                && (reverseEngineering.getIncludeProcedures().size() == 0) && 
(reverseEngineering.getExcludeProcedures().size() == 0));
-    }
-
-    private void initLevels() {
-        levels = new HashMap<>();
-
-        List<Class> rootChilds = new ArrayList<>();
-        rootChilds.add(Schema.class);
-        rootChilds.add(IncludeTable.class);
-        rootChilds.add(ExcludeTable.class);
-        rootChilds.add(IncludeColumn.class);
-        rootChilds.add(ExcludeColumn.class);
-        rootChilds.add(IncludeProcedure.class);
-        rootChilds.add(ExcludeProcedure.class);
-        levels.put(ReverseEngineering.class, rootChilds);
-
-        List<Class> catalogChilds = new ArrayList<>();
-        catalogChilds.add(Schema.class);
-        catalogChilds.add(IncludeTable.class);
-        catalogChilds.add(ExcludeTable.class);
-        catalogChilds.add(IncludeColumn.class);
-        catalogChilds.add(ExcludeColumn.class);
-        catalogChilds.add(IncludeProcedure.class);
-        catalogChilds.add(ExcludeProcedure.class);
-        levels.put(Catalog.class, catalogChilds);
-
-        List<Class> schemaChilds = new ArrayList<>();
-        schemaChilds.add(IncludeTable.class);
-        schemaChilds.add(ExcludeTable.class);
-        schemaChilds.add(IncludeColumn.class);
-        schemaChilds.add(ExcludeColumn.class);
-        schemaChilds.add(IncludeProcedure.class);
-        schemaChilds.add(ExcludeProcedure.class);
-        levels.put(Schema.class, schemaChilds);
-
-        List<Class> includeTableChilds = new ArrayList<>();
-        includeTableChilds.add(IncludeColumn.class);
-        includeTableChilds.add(ExcludeColumn.class);
-        levels.put(IncludeTable.class, includeTableChilds);
-        levels.put(ExcludeTable.class, null);
-        levels.put(IncludeColumn.class, null);
-        levels.put(ExcludeColumn.class, null);
-        levels.put(IncludeProcedure.class, null);
-        levels.put(ExcludeProcedure.class, null);
-    }
-
-    public void setTree(DbImportTree tree) {
-        this.tree = tree;
-    }
-
-    public JTree getTree() {
-        return tree;
-    }
-
-    boolean canBeInserted(DbImportTreeNode node) {
-        if (node == null) {
-            return false;
-        }
-        Class selectedObjectClass = node.getUserObject().getClass();
-        List<Class> childs = levels.get(selectedObjectClass);
-        return childs != null && childs.contains(insertableNodeClass);
-    }
-
-    boolean canInsert() {
-        if (selectedElement == null) {
-            return true;
-        }
-        if (parentElement != null) {
-            for (int i = 0; i < parentElement.getChildCount(); i++) {
-                DbImportTreeNode child = (DbImportTreeNode) 
parentElement.getChildAt(i);
-                if (child.getSimpleNodeName().equals(insertableNodeName)
-                        && (child.getUserObject().getClass() == 
insertableNodeClass)) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    protected void updateModel(boolean updateSelected) {
-        insertableNodeName = null;
-        DbImportModel model = (DbImportModel) tree.getModel();
-        getProjectController().setDirty(true);
-        TreePath savedPath = null;
-        if (!updateSelected) {
-            savedPath = new TreePath(parentElement.getPath());
-        }
-        model.reload(updateSelected ? selectedElement : parentElement);
-        if ((savedPath != null) && (parentElement.getUserObject().getClass() 
!= ReverseEngineering.class)) {
-            tree.setSelectionPath(savedPath);
-        }
-    }
-
-    void updateAfterInsert(boolean updateSelected) {
-        updateModel(updateSelected);
-        if (!movedFromDbSchema) {
-            if (updateSelected) {
-                tree.startEditingAtPath(new TreePath(((DbImportTreeNode) 
selectedElement.getLastChild()).getPath()));
-            } else {
-                tree.startEditingAtPath(new TreePath(((DbImportTreeNode) 
parentElement.getLastChild()).getPath()));
-            }
-        }
-        resetActionFlags();
-    }
-
-    public void resetActionFlags() {
-        movedFromDbSchema = false;
-        isMultipleAction = false;
-        insertableNodeName = "";
-    }
-
-    void setInsertableNodeName(String nodeName) {
-        this.insertableNodeName = nodeName;
-    }
-
-    void setMultipleAction(boolean multipleAction) {
-        isMultipleAction = multipleAction;
-    }
-
-    void setMovedFromDbSchema(boolean movedFromDbSchema) {
-        this.movedFromDbSchema = movedFromDbSchema;
-    }
-
-    void setFoundNode(DbImportTreeNode node) {
-        this.foundNode = node;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/51289d1c/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddCatalogAction.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddCatalogAction.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddCatalogAction.java
new file mode 100644
index 0000000..5ea7cc6
--- /dev/null
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddCatalogAction.java
@@ -0,0 +1,61 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.modeler.action.dbimport;
+
+import org.apache.cayenne.dbsync.reverse.dbimport.Catalog;
+import org.apache.cayenne.dbsync.reverse.dbimport.ReverseEngineering;
+import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.dialog.db.load.DbImportTreeNode;
+
+import java.awt.event.ActionEvent;
+
+/**
+ * @since 4.1
+ */
+public class AddCatalogAction extends TreeManipulationAction {
+
+    private static final String ACTION_NAME = "Add Catalog";
+    private static final String ICON_NAME = "icon-dbi-catalog.png";
+
+    public AddCatalogAction(Application application) {
+        super(ACTION_NAME, application);
+        insertableNodeClass = Catalog.class;
+    }
+
+    public String getIconName() {
+        return ICON_NAME;
+    }
+
+    @Override
+    public void performAction(ActionEvent e) {
+        ReverseEngineering reverseEngineeringOld = prepareElements();
+        Catalog newCatalog = new Catalog(name);
+        if (canBeInserted(selectedElement)) {
+            ((ReverseEngineering) 
selectedElement.getUserObject()).addCatalog(newCatalog);
+            selectedElement.add(new DbImportTreeNode(newCatalog));
+            updateSelected = true;
+        } else if (canInsert()) {
+            ((ReverseEngineering) 
parentElement.getUserObject()).addCatalog(newCatalog);
+            parentElement.add(new DbImportTreeNode(newCatalog));
+            updateSelected = false;
+        }
+        completeInserting(reverseEngineeringOld);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/51289d1c/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddExcludeColumnAction.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddExcludeColumnAction.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddExcludeColumnAction.java
new file mode 100644
index 0000000..ee1435d
--- /dev/null
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddExcludeColumnAction.java
@@ -0,0 +1,41 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.modeler.action.dbimport;
+
+import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeColumn;
+import org.apache.cayenne.modeler.Application;
+
+/**
+ * @since 4.1
+ */
+public class AddExcludeColumnAction extends AddPatternParamAction {
+
+    private static final String ACTION_NAME = "Add Exclude Column";
+    private static final String ICON_NAME = "icon-dbi-excludeColumn.png";
+
+    public AddExcludeColumnAction(Application application) {
+        super(ACTION_NAME, application);
+        insertableNodeClass = ExcludeColumn.class;
+    }
+
+    public String getIconName() {
+        return ICON_NAME;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/51289d1c/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddExcludeProcedureAction.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddExcludeProcedureAction.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddExcludeProcedureAction.java
new file mode 100644
index 0000000..ef844ba
--- /dev/null
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddExcludeProcedureAction.java
@@ -0,0 +1,41 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.modeler.action.dbimport;
+
+import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeProcedure;
+import org.apache.cayenne.modeler.Application;
+
+/**
+ * @since 4.1
+ */
+public class AddExcludeProcedureAction extends AddPatternParamAction {
+
+    private static final String ACTION_NAME = "Add Exclude Procedure";
+    private static final String ICON_NAME = "icon-dbi-excludeProcedure.png";
+
+    public AddExcludeProcedureAction(Application application) {
+        super(ACTION_NAME, application);
+        insertableNodeClass = ExcludeProcedure.class;
+    }
+
+    public String getIconName() {
+        return ICON_NAME;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/51289d1c/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddExcludeTableAction.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddExcludeTableAction.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddExcludeTableAction.java
new file mode 100644
index 0000000..b8dbeb8
--- /dev/null
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddExcludeTableAction.java
@@ -0,0 +1,41 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.modeler.action.dbimport;
+
+import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeTable;
+import org.apache.cayenne.modeler.Application;
+
+/**
+ * @since 4.1
+ */
+public class AddExcludeTableAction extends AddPatternParamAction {
+
+    private static final String ACTION_NAME = "Add Exclude Table";
+    private static final String ICON_NAME = "icon-dbi-excludeTable.png";
+
+    public AddExcludeTableAction(Application application) {
+        super(ACTION_NAME, application);
+        insertableNodeClass = ExcludeTable.class;
+    }
+
+    public String getIconName() {
+        return ICON_NAME;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/51289d1c/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddIncludeColumnAction.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddIncludeColumnAction.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddIncludeColumnAction.java
new file mode 100644
index 0000000..ea5c5ef
--- /dev/null
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddIncludeColumnAction.java
@@ -0,0 +1,41 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.modeler.action.dbimport;
+
+import org.apache.cayenne.dbsync.reverse.dbimport.IncludeColumn;
+import org.apache.cayenne.modeler.Application;
+
+/**
+ * @since 4.1
+ */
+public class AddIncludeColumnAction extends AddPatternParamAction {
+
+    private static final String ACTION_NAME = "Add Include Column";
+    private static final String ICON_NAME = "icon-dbi-includeColumn.png";
+
+    public AddIncludeColumnAction(Application application) {
+        super(ACTION_NAME, application);
+        insertableNodeClass = IncludeColumn.class;
+    }
+
+    public String getIconName() {
+        return ICON_NAME;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/51289d1c/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddIncludeProcedureAction.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddIncludeProcedureAction.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddIncludeProcedureAction.java
new file mode 100644
index 0000000..ca567b7
--- /dev/null
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddIncludeProcedureAction.java
@@ -0,0 +1,41 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.modeler.action.dbimport;
+
+import org.apache.cayenne.dbsync.reverse.dbimport.IncludeProcedure;
+import org.apache.cayenne.modeler.Application;
+
+/**
+ * @since 4.1
+ */
+public class AddIncludeProcedureAction extends AddPatternParamAction {
+
+    private static final String ACTION_NAME = "Add Include Procedure";
+    private static final String ICON_NAME = "icon-dbi-includeProcedure.png";
+
+    public AddIncludeProcedureAction(Application application) {
+        super(ACTION_NAME, application);
+        insertableNodeClass = IncludeProcedure.class;
+    }
+
+    public String getIconName() {
+        return ICON_NAME;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/51289d1c/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddIncludeTableAction.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddIncludeTableAction.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddIncludeTableAction.java
new file mode 100644
index 0000000..3d7c197
--- /dev/null
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddIncludeTableAction.java
@@ -0,0 +1,69 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.modeler.action.dbimport;
+
+import org.apache.cayenne.dbsync.reverse.dbimport.FilterContainer;
+import org.apache.cayenne.dbsync.reverse.dbimport.IncludeTable;
+import org.apache.cayenne.dbsync.reverse.dbimport.ReverseEngineering;
+import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.dialog.db.load.DbImportTreeNode;
+
+import javax.swing.tree.TreePath;
+import java.awt.event.ActionEvent;
+
+/**
+ * @since 4.1
+ */
+public class AddIncludeTableAction extends TreeManipulationAction {
+
+    private static final String ACTION_NAME = "Add Include Table";
+    private static final String ICON_NAME = "icon-dbi-includeTable.png";
+
+    public AddIncludeTableAction(Application application) {
+        super(ACTION_NAME, application);
+        insertableNodeClass = IncludeTable.class;
+    }
+
+    public String getIconName() {
+        return ICON_NAME;
+    }
+
+    @Override
+    public void performAction(ActionEvent e) {
+        ReverseEngineering reverseEngineeringOldCopy = prepareElements();
+        if (reverseEngineeringIsEmpty()) {
+            tree.getRootNode().removeAllChildren();
+        }
+        IncludeTable newTable = new IncludeTable(name);
+        if (canBeInserted(selectedElement)) {
+            ((FilterContainer) 
selectedElement.getUserObject()).addIncludeTable(newTable);
+            selectedElement.add(new DbImportTreeNode(newTable));
+            updateSelected = true;
+        } else {
+            if (parentElement == null) {
+                parentElement = tree.getRootNode();
+            }
+            ((FilterContainer) 
parentElement.getUserObject()).addIncludeTable(newTable);
+            parentElement.add(new DbImportTreeNode(newTable));
+            updateSelected = false;
+        }
+        completeInserting(reverseEngineeringOldCopy);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/51289d1c/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddPatternParamAction.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddPatternParamAction.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddPatternParamAction.java
new file mode 100644
index 0000000..640ffd8
--- /dev/null
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddPatternParamAction.java
@@ -0,0 +1,117 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.modeler.action.dbimport;
+
+import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeColumn;
+import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeProcedure;
+import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeTable;
+import org.apache.cayenne.dbsync.reverse.dbimport.FilterContainer;
+import org.apache.cayenne.dbsync.reverse.dbimport.IncludeColumn;
+import org.apache.cayenne.dbsync.reverse.dbimport.IncludeProcedure;
+import org.apache.cayenne.dbsync.reverse.dbimport.IncludeTable;
+import org.apache.cayenne.dbsync.reverse.dbimport.PatternParam;
+import org.apache.cayenne.dbsync.reverse.dbimport.ReverseEngineering;
+import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.dialog.db.load.DbImportTreeNode;
+
+import javax.swing.tree.TreePath;
+import java.awt.event.ActionEvent;
+
+/**
+ * @since 4.1
+ */
+public abstract class AddPatternParamAction extends TreeManipulationAction {
+
+    private Class paramClass;
+
+    AddPatternParamAction(String name, Application application) {
+        super(name, application);
+    }
+
+    private void addPatternParamToContainer(Class paramClass, Object 
selectedObject, String name, DbImportTreeNode node) {
+        FilterContainer container = (FilterContainer) selectedObject;
+        PatternParam element = null;
+        if (paramClass == ExcludeTable.class) {
+            element = new ExcludeTable(name);
+            container.addExcludeTable((ExcludeTable) element);
+        } else if (paramClass == IncludeColumn.class) {
+            element = new IncludeColumn(name);
+            container.addIncludeColumn((IncludeColumn) element);
+        } else if (paramClass == ExcludeColumn.class) {
+            element = new ExcludeColumn(name);
+            container.addExcludeColumn((ExcludeColumn) element);
+        } else if (paramClass == IncludeProcedure.class) {
+            element = new IncludeProcedure(name);
+            container.addIncludeProcedure((IncludeProcedure) element);
+        } else if (paramClass == ExcludeProcedure.class) {
+            element = new ExcludeProcedure(name);
+            container.addExcludeProcedure((ExcludeProcedure) element);
+        }
+        node.add(new DbImportTreeNode(element));
+    }
+
+    private void addPatternParamToIncludeTable(Class paramClass, Object 
selectedObject, String name, DbImportTreeNode node) {
+        IncludeTable includeTable = (IncludeTable) selectedObject;
+        PatternParam element = null;
+        if (paramClass == IncludeColumn.class) {
+            element = new IncludeColumn(name);
+            includeTable.addIncludeColumn((IncludeColumn) element);
+
+        } else if (paramClass == ExcludeColumn.class) {
+            element = new ExcludeColumn(name);
+            includeTable.addExcludeColumn((ExcludeColumn) element);
+        }
+        node.add(new DbImportTreeNode(element));
+    }
+
+    @Override
+    public void performAction(ActionEvent e) {
+        ReverseEngineering reverseEngineeringOldCopy = prepareElements();
+        Object selectedObject;
+        if (reverseEngineeringIsEmpty()) {
+            tree.getRootNode().removeAllChildren();
+        }
+        if (canBeInserted(selectedElement)) {
+            selectedObject = selectedElement.getUserObject();
+            if (selectedObject instanceof FilterContainer) {
+                addPatternParamToContainer(paramClass, selectedObject, name, 
selectedElement);
+            } else if (selectedObject instanceof IncludeTable) {
+                addPatternParamToIncludeTable(paramClass, selectedObject, 
name, selectedElement);
+            }
+            updateSelected = true;
+        } else {
+            if (parentElement == null) {
+                parentElement = tree.getRootNode();
+            }
+            selectedObject = parentElement.getUserObject();
+            if (selectedObject instanceof FilterContainer) {
+                addPatternParamToContainer(paramClass, selectedObject, name, 
parentElement);
+            } else if (selectedObject instanceof IncludeTable) {
+                addPatternParamToIncludeTable(paramClass, selectedObject, 
name, parentElement);
+            }
+            updateSelected = false;
+        }
+        completeInserting(reverseEngineeringOldCopy);
+    }
+
+    public void setParamClass(Class paramClass) {
+        this.paramClass = paramClass;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/51289d1c/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddSchemaAction.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddSchemaAction.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddSchemaAction.java
new file mode 100644
index 0000000..fa9562c
--- /dev/null
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/AddSchemaAction.java
@@ -0,0 +1,67 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.modeler.action.dbimport;
+
+import org.apache.cayenne.dbsync.reverse.dbimport.Catalog;
+import org.apache.cayenne.dbsync.reverse.dbimport.ReverseEngineering;
+import org.apache.cayenne.dbsync.reverse.dbimport.Schema;
+import org.apache.cayenne.dbsync.reverse.dbimport.SchemaContainer;
+import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.dialog.db.load.DbImportTreeNode;
+
+import java.awt.event.ActionEvent;
+
+/**
+ * @since 4.1
+ */
+public class AddSchemaAction extends TreeManipulationAction {
+
+    private static final String ACTION_NAME = "Add Schema";
+    private static final String ICON_NAME = "icon-dbi-schema.png";
+
+    public AddSchemaAction(Application application) {
+        super(ACTION_NAME, application);
+        insertableNodeClass = Schema.class;
+    }
+
+    public String getIconName() {
+        return ICON_NAME;
+    }
+
+    @Override
+    public void performAction(ActionEvent e) {
+        ReverseEngineering reverseEngineeringOldCopy = prepareElements();
+        Schema newSchema = new Schema(name);
+        if (canBeInserted(selectedElement)) {
+            ((SchemaContainer) 
selectedElement.getUserObject()).addSchema(newSchema);
+            selectedElement.add(new DbImportTreeNode(newSchema));
+            updateSelected = true;
+        } else if (canInsert()) {
+            if (parentElement.isReverseEngineering()) {
+                ((ReverseEngineering) 
parentElement.getUserObject()).addSchema(newSchema);
+            } else {
+                ((Catalog) parentElement.getUserObject()).addSchema(newSchema);
+            }
+            parentElement.add(new DbImportTreeNode(newSchema));
+            updateSelected = false;
+        }
+        completeInserting(reverseEngineeringOldCopy);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/51289d1c/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/DeleteNodeAction.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/DeleteNodeAction.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/DeleteNodeAction.java
new file mode 100644
index 0000000..94779d1
--- /dev/null
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/DeleteNodeAction.java
@@ -0,0 +1,170 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.modeler.action.dbimport;
+
+import org.apache.cayenne.dbsync.reverse.dbimport.Catalog;
+import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeColumn;
+import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeProcedure;
+import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeTable;
+import org.apache.cayenne.dbsync.reverse.dbimport.FilterContainer;
+import org.apache.cayenne.dbsync.reverse.dbimport.IncludeColumn;
+import org.apache.cayenne.dbsync.reverse.dbimport.IncludeProcedure;
+import org.apache.cayenne.dbsync.reverse.dbimport.IncludeTable;
+import org.apache.cayenne.dbsync.reverse.dbimport.PatternParam;
+import org.apache.cayenne.dbsync.reverse.dbimport.ReverseEngineering;
+import org.apache.cayenne.dbsync.reverse.dbimport.Schema;
+import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.dialog.db.load.DbImportTreeNode;
+import org.apache.cayenne.modeler.editor.dbimport.DbImportModel;
+import org.apache.cayenne.modeler.editor.dbimport.DbImportView;
+import org.apache.cayenne.modeler.editor.dbimport.DraggableTreePanel;
+
+import javax.swing.tree.TreePath;
+import java.awt.event.ActionEvent;
+import java.util.ArrayList;
+
+/**
+ * @since 4.1
+ */
+public class DeleteNodeAction extends TreeManipulationAction {
+
+    private static final String ACTION_NAME = "Delete";
+    private static final String ICON_NAME = "icon-trash.png";
+
+    private DraggableTreePanel panel;
+
+    public DeleteNodeAction(Application application) {
+        super(ACTION_NAME, application);
+    }
+
+    public String getIconName() {
+        return ICON_NAME;
+    }
+
+    private void removePatternParams(FilterContainer container, Object 
selectedObject) {
+        container.getExcludeTables().remove(selectedObject);
+        container.getIncludeColumns().remove(selectedObject);
+        container.getExcludeColumns().remove(selectedObject);
+        container.getIncludeProcedures().remove(selectedObject);
+        container.getExcludeProcedures().remove(selectedObject);
+    }
+
+    private void deleteChilds(Catalog catalog) {
+        Object selectedObject = this.selectedElement.getUserObject();
+        if (selectedObject instanceof Schema) {
+            catalog.getSchemas().remove(selectedObject);
+        } else if (selectedObject instanceof IncludeTable) {
+            catalog.getIncludeTables().remove(selectedObject);
+        } else if (selectedObject instanceof PatternParam) {
+            removePatternParams(catalog, selectedObject);
+        }
+    }
+
+    private void deleteChilds(Schema schema) {
+        Object selectedObject = this.selectedElement.getUserObject();
+        if (selectedObject instanceof IncludeTable) {
+            schema.getIncludeTables().remove(selectedObject);
+        } else if (selectedObject instanceof PatternParam) {
+            removePatternParams(schema, selectedObject);
+        }
+    }
+
+    private void deleteChilds(IncludeTable includeTable) {
+        Object selectedObject = this.selectedElement.getUserObject();
+        includeTable.getIncludeColumns().remove(selectedObject);
+        includeTable.getExcludeColumns().remove(selectedObject);
+    }
+
+    private void deleteChilds(ReverseEngineering reverseEngineering) {
+        Object selectedObject = this.selectedElement.getUserObject();
+        if (selectedObject instanceof Catalog) {
+            reverseEngineering.getCatalogs().remove(selectedObject);
+        } else if (selectedObject instanceof Schema) {
+            reverseEngineering.getSchemas().remove(selectedObject);
+        } else if (selectedObject instanceof IncludeTable) {
+            reverseEngineering.getIncludeTables().remove(selectedObject);
+        } else if (selectedObject instanceof ExcludeTable) {
+            reverseEngineering.getExcludeTables().remove(selectedObject);
+        } else if (selectedObject instanceof IncludeColumn) {
+            reverseEngineering.getIncludeColumns().remove(selectedObject);
+        } else if (selectedObject instanceof ExcludeColumn) {
+            reverseEngineering.getExcludeColumns().remove(selectedObject);
+        } else if (selectedObject instanceof IncludeProcedure) {
+            reverseEngineering.getIncludeProcedures().remove(selectedObject);
+        } else if (selectedObject instanceof ExcludeProcedure) {
+            reverseEngineering.getExcludeProcedures().remove(selectedObject);
+        }
+    }
+
+    private void updateParentChilds() {
+        DbImportModel model = (DbImportModel) tree.getModel();
+        model.removeNodeFromParent(selectedElement);
+        getProjectController().setDirty(true);
+        model.reload(parentElement);
+    }
+
+    @Override
+    public void performAction(ActionEvent e) {
+        tree.stopEditing();
+        final TreePath[] paths = tree.getSelectionPaths();
+        final DbImportView rootParent = ((DbImportView) 
panel.getParent().getParent());
+        rootParent.getLoadDbSchemaButton().setEnabled(false);
+        rootParent.getReverseEngineeringProgress().setVisible(true);
+        if (paths != null) {
+            ReverseEngineering reverseEngineeringOldCopy = new 
ReverseEngineering(tree.getReverseEngineering());
+            rootParent.lockToolbarButtons();
+            for (TreePath path : paths) {
+                selectedElement = (DbImportTreeNode) 
path.getLastPathComponent();
+                parentElement = (DbImportTreeNode) selectedElement.getParent();
+                if (parentElement != null) {
+                    Object parentUserObject = parentElement.getUserObject();
+                    if (parentUserObject instanceof ReverseEngineering) {
+                        ReverseEngineering reverseEngineering = 
(ReverseEngineering) parentUserObject;
+                        deleteChilds(reverseEngineering);
+                    } else if (parentUserObject instanceof Catalog) {
+                        Catalog catalog = (Catalog) parentUserObject;
+                        deleteChilds(catalog);
+                    } else if (parentUserObject instanceof Schema) {
+                        Schema schema = (Schema) parentUserObject;
+                        deleteChilds(schema);
+                    } else if (parentUserObject instanceof IncludeTable) {
+                        IncludeTable includeTable = (IncludeTable) 
parentUserObject;
+                        deleteChilds(includeTable);
+                    }
+                }
+            }
+            if (paths.length > 1) {
+                getProjectController().setDirty(true);
+                ArrayList<DbImportTreeNode> expandList = 
tree.getTreeExpandList();
+                
tree.translateReverseEngineeringToTree(tree.getReverseEngineering(), false);
+                tree.expandTree(expandList);
+            } else {
+                updateParentChilds();
+            }
+            putReverseEngineeringToUndoManager(reverseEngineeringOldCopy);
+            rootParent.getLoadDbSchemaButton().setEnabled(true);
+            rootParent.getReverseEngineeringProgress().setVisible(false);
+        }
+    }
+
+    public void setPanel(DraggableTreePanel panel) {
+        this.panel = panel;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/51289d1c/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/EditNodeAction.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/EditNodeAction.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/EditNodeAction.java
new file mode 100644
index 0000000..5ae0591
--- /dev/null
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/EditNodeAction.java
@@ -0,0 +1,88 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.modeler.action.dbimport;
+
+import org.apache.cayenne.dbsync.reverse.dbimport.FilterContainer;
+import org.apache.cayenne.dbsync.reverse.dbimport.PatternParam;
+import org.apache.cayenne.dbsync.reverse.dbimport.ReverseEngineering;
+import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.dialog.db.load.DbImportTreeNode;
+import org.apache.cayenne.util.Util;
+
+import java.awt.event.ActionEvent;
+
+/**
+ * @since 4.1
+ */
+public class EditNodeAction extends TreeManipulationAction {
+
+    private static final String ACTION_NAME = "Rename";
+    private static final String ICON_NAME = "icon-edit.png";
+
+    private String actionName;
+
+    public EditNodeAction(Application application) {
+        super(ACTION_NAME, application);
+    }
+
+    public String getIconName() {
+        return ICON_NAME;
+    }
+
+    @Override
+    public void performAction(ActionEvent e) {
+        if (tree.isEditing()) {
+            return;
+        }
+        if (e != null) {
+            if (tree.getSelectionPath() != null) {
+                tree.startEditingAtPath(tree.getSelectionPath());
+            }
+        }
+        if (actionName == null) {
+            return;
+        }
+        if (tree.getSelectionPath() != null) {
+            selectedElement = tree.getSelectedNode();
+            parentElement = (DbImportTreeNode) selectedElement.getParent();
+            if (parentElement != null) {
+                Object selectedObject = selectedElement.getUserObject();
+                ReverseEngineering reverseEngineeringOldCopy = new 
ReverseEngineering(tree.getReverseEngineering());
+                if (!Util.isEmptyString(actionName)) {
+                    if (selectedObject instanceof FilterContainer) {
+                        ((FilterContainer) selectedObject).setName(actionName);
+                    } else if (selectedObject instanceof PatternParam) {
+                        ((PatternParam) selectedObject).setPattern(actionName);
+                    }
+                    updateModel(true);
+                    selectedElement = null;
+                }
+                if (!actionName.equals(EMPTY_NAME)) {
+                    
putReverseEngineeringToUndoManager(reverseEngineeringOldCopy);
+                }
+            }
+        }
+    }
+
+    public void setActionName(String name) {
+        this.actionName = name;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/51289d1c/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/MoveImportNodeAction.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/MoveImportNodeAction.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/MoveImportNodeAction.java
new file mode 100644
index 0000000..cf8f44e
--- /dev/null
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/MoveImportNodeAction.java
@@ -0,0 +1,238 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.modeler.action.dbimport;
+
+import org.apache.cayenne.dbsync.reverse.dbimport.Catalog;
+import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeColumn;
+import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeProcedure;
+import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeTable;
+import org.apache.cayenne.dbsync.reverse.dbimport.IncludeColumn;
+import org.apache.cayenne.dbsync.reverse.dbimport.IncludeProcedure;
+import org.apache.cayenne.dbsync.reverse.dbimport.IncludeTable;
+import org.apache.cayenne.dbsync.reverse.dbimport.ReverseEngineering;
+import org.apache.cayenne.dbsync.reverse.dbimport.Schema;
+import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.dialog.db.load.DbImportTreeNode;
+import org.apache.cayenne.modeler.editor.dbimport.DbImportTree;
+import org.apache.cayenne.modeler.editor.dbimport.DbImportView;
+import org.apache.cayenne.modeler.editor.dbimport.DraggableTreePanel;
+import org.apache.cayenne.modeler.undo.DbImportTreeUndoableEdit;
+import org.apache.cayenne.modeler.util.CayenneAction;
+
+import javax.swing.tree.TreePath;
+import java.awt.event.ActionEvent;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+
+/**
+ * @since 4.1
+ */
+public class MoveImportNodeAction extends CayenneAction {
+
+    private static final String ICON_NAME = "icon-backward.png";
+    private static final String ACTION_NAME = "Include";
+    private static final String EMPTY_NAME = "";
+
+    private DbImportTree sourceTree;
+    private DbImportTree targetTree;
+    private DraggableTreePanel panel;
+    protected boolean moveInverted;
+    private Map<Class, Class> classMap;
+
+    public MoveImportNodeAction(Application application) {
+        super(ACTION_NAME, application);
+    }
+
+    MoveImportNodeAction(String actionName, Application application) {
+        super(actionName, application);
+        initMap();
+    }
+
+    private void initMap() {
+        classMap = new HashMap<>();
+        classMap.put(IncludeTable.class, ExcludeTable.class);
+        classMap.put(IncludeColumn.class, ExcludeColumn.class);
+        classMap.put(IncludeProcedure.class, ExcludeProcedure.class);
+        classMap.put(Schema.class, Schema.class);
+        classMap.put(Catalog.class, Catalog.class);
+    }
+
+    public String getIconName() {
+        return ICON_NAME;
+    }
+
+    private boolean canInsert(TreePath path, DbImportTreeNode foundNode) {
+        DbImportTreeNode sourceElement = (DbImportTreeNode) 
path.getLastPathComponent();
+        DbImportTreeNode selectedElement;
+        if (foundNode == null) {
+            if (targetTree.getSelectionPath() != null) {
+                DbImportTreeNode node = targetTree.getSelectedNode();
+                if ((node.getUserObject().getClass() == Catalog.class)
+                        || (node.getUserObject().getClass() == Schema.class)
+                        || (node.getUserObject().getClass() == 
ReverseEngineering.class)) {
+                    selectedElement = targetTree.getSelectedNode();
+                } else {
+                    selectedElement = (DbImportTreeNode) 
targetTree.getSelectionPath().
+                            getParentPath().getLastPathComponent();
+                }
+            } else {
+                selectedElement = targetTree.getRootNode();
+            }
+        } else {
+            selectedElement = foundNode;
+        }
+        if ((nodeClassesIsSameTypes(sourceElement, selectedElement))
+                && 
(sourceElement.getSimpleNodeName().equals(selectedElement.getSimpleNodeName())))
 {
+            return false;
+        }
+        int childCount = selectedElement.getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            DbImportTreeNode child = (DbImportTreeNode) 
selectedElement.getChildAt(i);
+            if ((nodeClassesIsSameTypes(sourceElement, child))
+                && 
(sourceElement.getSimpleNodeName().equals(child.getSimpleNodeName()))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public void performAction(ActionEvent e) {
+        TreePath[] paths = sourceTree.getSelectionPaths();
+        TreeManipulationAction action = null;
+        String insertableName = EMPTY_NAME;
+        DbImportView rootParent = (DbImportView) panel.getParent().getParent();
+        rootParent.getReverseEngineeringProgress().setVisible(true);
+        if (paths != null) {
+            boolean isChanged = false;
+            ReverseEngineering reverseEngineeringOldCopy = new 
ReverseEngineering(targetTree.getReverseEngineering());
+            try {
+                for (TreePath path : paths) {
+                    DbImportTreeNode selectedElement = (DbImportTreeNode) 
path.getLastPathComponent();
+                    DbImportTreeNode previousNode;
+                    DbImportTreeNode foundNode = 
targetTree.findNodeByParentsChain(
+                            targetTree.getRootNode(), selectedElement, 0
+                    );
+                    // If parent nodes from db schema doesn't exist, create it
+                    if (foundNode == null) {
+                        for (int i = selectedElement.getParents().size() - 2; 
i >= 0; i--) {
+                            DbImportTreeNode insertedNode = 
selectedElement.getParents().get(i);
+                            previousNode = 
targetTree.findNodeByParentsChain(targetTree.getRootNode(), insertedNode, 0);
+                            if (previousNode == null) {
+                                previousNode = targetTree.getRootNode();
+                            }
+                            TreeManipulationAction manipulationAction = 
panel.getActionByNodeType(
+                                    insertedNode.getUserObject().getClass()
+                            );
+                            if (canInsert(new 
TreePath(insertedNode.getPath()), previousNode)) {
+                                manipulationAction.setFoundNode(previousNode);
+                                
manipulationAction.setInsertableNodeName(insertedNode.getSimpleNodeName());
+                                manipulationAction.setTree(targetTree);
+                                manipulationAction.setMovedFromDbSchema(true);
+                                manipulationAction.actionPerformed(e);
+                                manipulationAction.setFoundNode(null);
+                                manipulationAction.setMultipleAction(false);
+                            }
+                        }
+                    }
+                    // Again find node where we insert our node
+                    foundNode = 
targetTree.findNodeByParentsChain(targetTree.getRootNode(), selectedElement, 0);
+                    if (!moveInverted) {
+                        action = 
panel.getActionByNodeType(selectedElement.getUserObject().getClass());
+                    } else {
+                        action = 
panel.getActionByNodeType(classMap.get(selectedElement.getUserObject().getClass()));
+                    }
+                    if (action != null) {
+                        if (paths.length > 1) {
+                            action.setMultipleAction(true);
+                        } else {
+                            action.setMultipleAction(false);
+                        }
+                        if (canInsert(path, foundNode)) {
+                            insertableName = 
selectedElement.getSimpleNodeName();
+                            action.setFoundNode(foundNode);
+                            
action.setInsertableNodeName(Matcher.quoteReplacement(insertableName));
+                            action.setTree(targetTree);
+                            action.setMovedFromDbSchema(true);
+                            action.actionPerformed(e);
+                            action.setFoundNode(null);
+                            action.resetActionFlags();
+                            isChanged = true;
+                            sourceTree.setSelectionRow(-1);
+                            panel.getMoveButton().setEnabled(false);
+                            panel.getMoveInvertButton().setEnabled(false);
+                        }
+                    }
+                }
+                if ((paths.length > 1) && (targetTree.getSelectionPath() != 
null)) {
+                    getProjectController().setDirty(true);
+                    ArrayList<DbImportTreeNode> expandList = 
targetTree.getTreeExpandList();
+                    
targetTree.translateReverseEngineeringToTree(targetTree.getReverseEngineering(),
 false);
+                    targetTree.expandTree(expandList);
+                }
+                if ((isChanged) && (!insertableName.equals(EMPTY_NAME))) {
+                    ReverseEngineering reverseEngineeringNewCopy = new 
ReverseEngineering(targetTree.getReverseEngineering());
+                    DbImportTreeUndoableEdit undoableEdit = new 
DbImportTreeUndoableEdit(
+                            reverseEngineeringOldCopy, 
reverseEngineeringNewCopy, targetTree, getProjectController()
+                    );
+                    
getProjectController().getApplication().getUndoManager().addEdit(undoableEdit);
+                }
+            } finally {
+                rootParent.getReverseEngineeringProgress().setVisible(false);
+                if (action != null) {
+                    action.resetActionFlags();
+                }
+            }
+        }
+    }
+
+    private boolean nodeClassesIsSameTypes(DbImportTreeNode sourceElement, 
DbImportTreeNode selectedElement) {
+        if (sourceElement.getUserObject().getClass() == 
selectedElement.getUserObject().getClass()) {
+            return true;
+        }
+        if (sourceElement.getUserObject().getClass() == IncludeTable.class) {
+            if ((selectedElement.getUserObject().getClass() == 
IncludeTable.class)
+                || (selectedElement.getUserObject().getClass() == 
ExcludeTable.class)) {
+                return true;
+            }
+        }
+        if (sourceElement.getUserObject().getClass() == 
IncludeProcedure.class) {
+            if ((selectedElement.getUserObject().getClass() == 
IncludeProcedure.class)
+                    || (selectedElement.getUserObject().getClass() == 
ExcludeProcedure.class)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public void setSourceTree(DbImportTree sourceTree) {
+        this.sourceTree = sourceTree;
+    }
+
+    public void setTargetTree(DbImportTree targetTree) {
+        this.targetTree = targetTree;
+    }
+
+    public void setPanel(DraggableTreePanel panel) {
+        this.panel = panel;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/51289d1c/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/MoveInvertNodeAction.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/MoveInvertNodeAction.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/MoveInvertNodeAction.java
new file mode 100644
index 0000000..dd7da10
--- /dev/null
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/MoveInvertNodeAction.java
@@ -0,0 +1,35 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.modeler.action.dbimport;
+
+import org.apache.cayenne.modeler.Application;
+
+/**
+ * @since 4.1
+ */
+public class MoveInvertNodeAction extends MoveImportNodeAction {
+
+    private static final String ACTION_NAME = "Exclude";
+
+    public MoveInvertNodeAction(Application application) {
+        super(ACTION_NAME, application);
+        moveInverted = true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/51289d1c/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/TreeManipulationAction.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/TreeManipulationAction.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/TreeManipulationAction.java
new file mode 100644
index 0000000..23e6c65
--- /dev/null
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/TreeManipulationAction.java
@@ -0,0 +1,243 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.modeler.action.dbimport;
+
+import org.apache.cayenne.dbsync.reverse.dbimport.Catalog;
+import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeColumn;
+import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeProcedure;
+import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeTable;
+import org.apache.cayenne.dbsync.reverse.dbimport.IncludeColumn;
+import org.apache.cayenne.dbsync.reverse.dbimport.IncludeProcedure;
+import org.apache.cayenne.dbsync.reverse.dbimport.IncludeTable;
+import org.apache.cayenne.dbsync.reverse.dbimport.ReverseEngineering;
+import org.apache.cayenne.dbsync.reverse.dbimport.Schema;
+import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.dialog.db.load.DbImportTreeNode;
+import org.apache.cayenne.modeler.editor.dbimport.DbImportModel;
+import org.apache.cayenne.modeler.editor.dbimport.DbImportTree;
+import org.apache.cayenne.modeler.undo.DbImportTreeUndoableEdit;
+import org.apache.cayenne.modeler.util.CayenneAction;
+
+import javax.swing.JTree;
+import javax.swing.tree.TreePath;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @since 4.1
+ */
+public abstract class TreeManipulationAction extends CayenneAction {
+
+    static final String EMPTY_NAME = "";
+
+    protected DbImportTree tree;
+    protected DbImportTreeNode selectedElement;
+    DbImportTreeNode parentElement;
+    DbImportTreeNode foundNode;
+    String insertableNodeName;
+    Class insertableNodeClass;
+    boolean isMultipleAction;
+    private boolean movedFromDbSchema;
+    private Map<Class, List<Class>> levels;
+    protected String name;
+    protected boolean updateSelected;
+
+    public TreeManipulationAction(String name, Application application) {
+        super(name, application);
+        initLevels();
+    }
+
+    void completeInserting(ReverseEngineering reverseEngineeringOldCopy) {
+        if (!isMultipleAction) {
+            updateAfterInsert();
+        }
+        if ((!isMultipleAction) && (!insertableNodeName.equals(EMPTY_NAME))) {
+            putReverseEngineeringToUndoManager(reverseEngineeringOldCopy);
+        }
+    }
+
+    private String getNodeName() {
+        return insertableNodeName != null ? insertableNodeName : EMPTY_NAME;
+    }
+
+    protected ReverseEngineering prepareElements() {
+        name = getNodeName();
+        tree.stopEditing();
+        if (tree.getSelectionPath() == null) {
+            TreePath root = new TreePath(tree.getRootNode());
+            tree.setSelectionPath(root);
+        }
+        if (foundNode == null) {
+            selectedElement = tree.getSelectedNode();
+        } else {
+            selectedElement = foundNode;
+        }
+        parentElement = (DbImportTreeNode) selectedElement.getParent();
+        if (parentElement == null) {
+            parentElement = selectedElement;
+        }
+        if (reverseEngineeringIsEmpty()) {
+            tree.getRootNode().removeAllChildren();
+        }
+        return new ReverseEngineering(tree.getReverseEngineering());
+    }
+
+    protected void putReverseEngineeringToUndoManager(ReverseEngineering 
reverseEngineeringOldCopy) {
+        ReverseEngineering reverseEngineeringNewCopy = new 
ReverseEngineering(tree.getReverseEngineering());
+        DbImportTreeUndoableEdit undoableEdit = new DbImportTreeUndoableEdit(
+                reverseEngineeringOldCopy, reverseEngineeringNewCopy, tree, 
getProjectController()
+        );
+        
getProjectController().getApplication().getUndoManager().addEdit(undoableEdit);
+    }
+
+    boolean reverseEngineeringIsEmpty() {
+        ReverseEngineering reverseEngineering = tree.getReverseEngineering();
+        return ((reverseEngineering.getCatalogs().size() == 0) && 
(reverseEngineering.getSchemas().size() == 0)
+                && (reverseEngineering.getIncludeTables().size() == 0) && 
(reverseEngineering.getExcludeTables().size() == 0)
+                && (reverseEngineering.getIncludeColumns().size() == 0) && 
(reverseEngineering.getExcludeColumns().size() == 0)
+                && (reverseEngineering.getIncludeProcedures().size() == 0) && 
(reverseEngineering.getExcludeProcedures().size() == 0));
+    }
+
+    private void initLevels() {
+        levels = new HashMap<>();
+
+        List<Class> rootChilds = new ArrayList<>();
+        rootChilds.add(Schema.class);
+        rootChilds.add(IncludeTable.class);
+        rootChilds.add(ExcludeTable.class);
+        rootChilds.add(IncludeColumn.class);
+        rootChilds.add(ExcludeColumn.class);
+        rootChilds.add(IncludeProcedure.class);
+        rootChilds.add(ExcludeProcedure.class);
+        levels.put(ReverseEngineering.class, rootChilds);
+
+        List<Class> catalogChilds = new ArrayList<>();
+        catalogChilds.add(Schema.class);
+        catalogChilds.add(IncludeTable.class);
+        catalogChilds.add(ExcludeTable.class);
+        catalogChilds.add(IncludeColumn.class);
+        catalogChilds.add(ExcludeColumn.class);
+        catalogChilds.add(IncludeProcedure.class);
+        catalogChilds.add(ExcludeProcedure.class);
+        levels.put(Catalog.class, catalogChilds);
+
+        List<Class> schemaChilds = new ArrayList<>();
+        schemaChilds.add(IncludeTable.class);
+        schemaChilds.add(ExcludeTable.class);
+        schemaChilds.add(IncludeColumn.class);
+        schemaChilds.add(ExcludeColumn.class);
+        schemaChilds.add(IncludeProcedure.class);
+        schemaChilds.add(ExcludeProcedure.class);
+        levels.put(Schema.class, schemaChilds);
+
+        List<Class> includeTableChilds = new ArrayList<>();
+        includeTableChilds.add(IncludeColumn.class);
+        includeTableChilds.add(ExcludeColumn.class);
+        levels.put(IncludeTable.class, includeTableChilds);
+        levels.put(ExcludeTable.class, null);
+        levels.put(IncludeColumn.class, null);
+        levels.put(ExcludeColumn.class, null);
+        levels.put(IncludeProcedure.class, null);
+        levels.put(ExcludeProcedure.class, null);
+    }
+
+    public void setTree(DbImportTree tree) {
+        this.tree = tree;
+    }
+
+    public JTree getTree() {
+        return tree;
+    }
+
+    boolean canBeInserted(DbImportTreeNode node) {
+        if (node == null) {
+            return false;
+        }
+        Class selectedObjectClass = node.getUserObject().getClass();
+        List<Class> childs = levels.get(selectedObjectClass);
+        return childs != null && childs.contains(insertableNodeClass);
+    }
+
+    boolean canInsert() {
+        if (selectedElement == null) {
+            return true;
+        }
+        if (parentElement != null) {
+            for (int i = 0; i < parentElement.getChildCount(); i++) {
+                DbImportTreeNode child = (DbImportTreeNode) 
parentElement.getChildAt(i);
+                if (child.getSimpleNodeName().equals(insertableNodeName)
+                        && (child.getUserObject().getClass() == 
insertableNodeClass)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    protected void updateModel(boolean updateSelected) {
+        insertableNodeName = null;
+        DbImportModel model = (DbImportModel) tree.getModel();
+        getProjectController().setDirty(true);
+        TreePath savedPath = null;
+        if (!updateSelected) {
+            savedPath = new TreePath(parentElement.getPath());
+        }
+        model.reload(updateSelected ? selectedElement : parentElement);
+        if ((savedPath != null) && (parentElement.getUserObject().getClass() 
!= ReverseEngineering.class)) {
+            tree.setSelectionPath(savedPath);
+        }
+    }
+
+    void updateAfterInsert() {
+        updateModel(updateSelected);
+        if (!movedFromDbSchema) {
+            if (updateSelected) {
+                tree.startEditingAtPath(new TreePath(((DbImportTreeNode) 
selectedElement.getLastChild()).getPath()));
+            } else {
+                tree.startEditingAtPath(new TreePath(((DbImportTreeNode) 
parentElement.getLastChild()).getPath()));
+            }
+        }
+        resetActionFlags();
+    }
+
+    public void resetActionFlags() {
+        movedFromDbSchema = false;
+        isMultipleAction = false;
+        insertableNodeName = "";
+    }
+
+    void setInsertableNodeName(String nodeName) {
+        this.insertableNodeName = nodeName;
+    }
+
+    void setMultipleAction(boolean multipleAction) {
+        isMultipleAction = multipleAction;
+    }
+
+    void setMovedFromDbSchema(boolean movedFromDbSchema) {
+        this.movedFromDbSchema = movedFromDbSchema;
+    }
+
+    void setFoundNode(DbImportTreeNode node) {
+        this.foundNode = node;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/51289d1c/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/DbLoaderContext.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/DbLoaderContext.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/DbLoaderContext.java
index 9f499f7..4f22c77 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/DbLoaderContext.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/DbLoaderContext.java
@@ -34,7 +34,7 @@ import 
org.apache.cayenne.dbsync.reverse.filters.FiltersConfigBuilder;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.ProjectController;
-import org.apache.cayenne.modeler.editor.DbImportView;
+import org.apache.cayenne.modeler.editor.dbimport.DbImportView;
 import org.apache.cayenne.modeler.pref.DBConnectionInfo;
 import org.apache.cayenne.util.Util;
 import org.slf4j.Logger;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/51289d1c/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/DefaultPopUpMenu.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/DefaultPopUpMenu.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/DefaultPopUpMenu.java
index 8fa7ae1..8603337 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/DefaultPopUpMenu.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/DefaultPopUpMenu.java
@@ -20,8 +20,8 @@
 package org.apache.cayenne.modeler.dialog.db.load;
 
 import org.apache.cayenne.modeler.ProjectController;
-import org.apache.cayenne.modeler.action.DeleteNodeAction;
-import org.apache.cayenne.modeler.action.EditNodeAction;
+import org.apache.cayenne.modeler.action.dbimport.DeleteNodeAction;
+import org.apache.cayenne.modeler.action.dbimport.EditNodeAction;
 
 import javax.swing.JMenuItem;
 import javax.swing.JPopupMenu;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/51289d1c/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/ModelerDbImportAction.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/ModelerDbImportAction.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/ModelerDbImportAction.java
index 1109753..22924ac 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/ModelerDbImportAction.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/ModelerDbImportAction.java
@@ -26,11 +26,8 @@ import 
org.apache.cayenne.configuration.server.DbAdapterFactory;
 import org.apache.cayenne.configuration.xml.DataChannelMetaData;
 import org.apache.cayenne.dbsync.merge.factory.MergerTokenFactoryProvider;
 import org.apache.cayenne.dbsync.merge.token.MergerToken;
-import org.apache.cayenne.dbsync.reverse.filters.FiltersConfig;
-import org.apache.cayenne.dbsync.reverse.filters.PatternFilter;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.map.DataMap;
-import org.apache.cayenne.map.Procedure;
 import org.apache.cayenne.project.ProjectSaver;
 import org.apache.cayenne.dbsync.reverse.dbimport.DbImportConfiguration;
 import org.apache.cayenne.dbsync.reverse.dbimport.DefaultDbImportAction;
@@ -88,43 +85,25 @@ public class ModelerDbImportAction extends 
DefaultDbImportAction {
     }
 
     @Override
-    protected boolean syncProcedures(DataMap targetDataMap, DataMap 
loadedDataMap, FiltersConfig filters) {
-        Collection<Procedure> procedures = loadedDataMap.getProcedures();
-
-        boolean hasChanges = false;
-        for (Procedure procedure : procedures) {
-            PatternFilter proceduresFilter = 
filters.proceduresFilter(procedure.getCatalog(), procedure.getSchema());
-            if (proceduresFilter == null || 
!proceduresFilter.isIncluded(procedure.getName())) {
-                continue;
-            }
+    protected void addMessageToLogs(String message, List<String> messages) {
+        String formattedMessage = String.format("    %-20s", message);
+        messages.add(formattedMessage);
+        resultDialog.addRowToOutput(formattedMessage);
+        isNothingChanged = false;
+    }
 
-            Procedure oldProcedure = 
targetDataMap.getProcedure(procedure.getName());
-            // maybe we need to compare oldProcedure's and procedure's fully 
qualified names?
-            if (oldProcedure != null) {
-                targetDataMap.removeProcedure(procedure.getName());
-                String logString = String.format("    %-20s %s", "Replace 
procedure ", procedure.getName());
-                logger.info(logString);
-                resultDialog.addRowToOutput(logString);
-            } else {
-                String logString = String.format("    %-20s %s", "Add new 
procedure ", procedure.getName());
-                logger.info(logString);
-                resultDialog.addRowToOutput(logString);
-            }
-            targetDataMap.addProcedure(procedure);
-            if (!resultDialog.isVisible()) {
-                resultDialog.setVisible(true);
-            }
-            isNothingChanged = false;
-            hasChanges = true;
-        }
-        if ((isNothingChanged)) {
+    @Override
+    protected void logMessages(List<String> messages) {
+        super.logMessages(messages);
+        if (isNothingChanged) {
             JOptionPane optionPane = new JOptionPane("Detected changes: No 
changes to import.", JOptionPane.PLAIN_MESSAGE);
             JDialog dialog = optionPane.createDialog(DIALOG_TITLE);
             dialog.setModal(false);
             dialog.setAlwaysOnTop(true);
             dialog.setVisible(true);
+        } else if (!resultDialog.isVisible()) {
+            resultDialog.setVisible(true);
         }
-        return hasChanges;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cayenne/blob/51289d1c/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/RootPopUpMenu.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/RootPopUpMenu.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/RootPopUpMenu.java
index 0e3ef1d..f32030b 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/RootPopUpMenu.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/db/load/RootPopUpMenu.java
@@ -19,14 +19,14 @@
 
 package org.apache.cayenne.modeler.dialog.db.load;
 
-import org.apache.cayenne.modeler.action.AddCatalogAction;
-import org.apache.cayenne.modeler.action.AddExcludeColumnAction;
-import org.apache.cayenne.modeler.action.AddExcludeProcedureAction;
-import org.apache.cayenne.modeler.action.AddExcludeTableAction;
-import org.apache.cayenne.modeler.action.AddIncludeColumnAction;
-import org.apache.cayenne.modeler.action.AddIncludeProcedureAction;
-import org.apache.cayenne.modeler.action.AddIncludeTableAction;
-import org.apache.cayenne.modeler.action.AddSchemaAction;
+import org.apache.cayenne.modeler.action.dbimport.AddCatalogAction;
+import org.apache.cayenne.modeler.action.dbimport.AddExcludeColumnAction;
+import org.apache.cayenne.modeler.action.dbimport.AddExcludeProcedureAction;
+import org.apache.cayenne.modeler.action.dbimport.AddExcludeTableAction;
+import org.apache.cayenne.modeler.action.dbimport.AddIncludeColumnAction;
+import org.apache.cayenne.modeler.action.dbimport.AddIncludeProcedureAction;
+import org.apache.cayenne.modeler.action.dbimport.AddIncludeTableAction;
+import org.apache.cayenne.modeler.action.dbimport.AddSchemaAction;
 
 import javax.swing.JMenu;
 import javax.swing.JMenuItem;

http://git-wip-us.apache.org/repos/asf/cayenne/blob/51289d1c/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ColorTreeRenderer.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ColorTreeRenderer.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ColorTreeRenderer.java
deleted file mode 100644
index da0d474..0000000
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ColorTreeRenderer.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.modeler.editor;
-
-import org.apache.cayenne.dbsync.reverse.dbimport.IncludeProcedure;
-import org.apache.cayenne.modeler.dialog.db.load.DbImportTreeNode;
-
-import javax.swing.JTree;
-import java.awt.Color;
-import java.awt.Component;
-
-import static 
org.apache.cayenne.modeler.editor.DbImportNodeHandler.LABEL_COLOR;
-import static 
org.apache.cayenne.modeler.editor.DbImportNodeHandler.NON_INCLUDE_COLOR;
-
-/**
- * @since 4.1
- */
-public class ColorTreeRenderer extends DbImportTreeCellRenderer {
-
-    private DbImportNodeHandler handler;
-    private DbImportTree reverseEngineeringTree;
-
-
-    public ColorTreeRenderer() {
-        super();
-        handler = new DbImportNodeHandler();
-    }
-
-    @Override
-    public Component getTreeCellRendererComponent(JTree tree, Object value,
-                                                  boolean sel,
-                                                  boolean expanded,
-                                                  boolean leaf, int row,
-                                                  boolean hasFocus) {
-        super.getTreeCellRendererComponent(tree, value, sel,
-                expanded, leaf, row, hasFocus);
-        DbImportTree renderedTree = (DbImportTree) tree;
-        handler.setDbSchemaNode(node);
-        if (node.isLabel()) {
-            setForeground(LABEL_COLOR);
-            return this;
-        }
-        if (handler.isContainer(node) || 
(handler.isFirstNodeIsPrimitive(renderedTree))) {
-            handler.setHasEntitiesInEmptyContainer(false);
-        }
-        if (selected) {
-            setForeground(Color.BLACK);
-            node.setColorized(node.isColorized());
-            return this;
-        }
-        DbImportTreeNode root;
-        handler.findFirstLevelIncludeTable();
-        if (!handler.checkTreesLevels(renderedTree)) {
-            setForeground(NON_INCLUDE_COLOR);
-            node.setColorized(false);
-            return this;
-        }
-        if (reverseEngineeringTree.getSelectionPath() != null) {
-            root = reverseEngineeringTree.getSelectedNode();
-        } else {
-            root = reverseEngineeringTree.getRootNode();
-        }
-        renderedTree.getRootNode().setColorized(true);
-
-        int bypassResult = handler.bypassTree(root);
-        if (bypassResult > 0) {
-            // Case on IncludeProcedure on zero level is selected
-            if (root.getUserObject().getClass() == IncludeProcedure.class) {
-                if (handler.nodesIsEqual(root)) {
-                    setForeground(handler.getColorByNodeType(root));
-                    node.setColorized(true);
-                    return this;
-                } else {
-                    setForeground(NON_INCLUDE_COLOR);
-                    node.setColorized(false);
-                    return this;
-                }
-            }
-            // If ReverseEngineering doesn't have catalogs or schemas on zero 
level
-            if (!handler.isExistCatalogsOrSchemas()) {
-                if ((root.isExcludeTable()) || (root.isExcludeProcedure())) {
-                    if (handler.nodesIsEqual(root)) {
-                        setForeground(handler.getColorByNodeType(root));
-                        node.setColorized(true);
-                        return this;
-                    }
-                    setForeground(NON_INCLUDE_COLOR);
-                    node.setColorized(false);
-                    return this;
-                }
-                if (root.equals(node)) {
-                    setForeground(handler.getColorByNodeType(root));
-                    node.setColorized(true);
-                    return this;
-                }
-            }
-            // Recursion painting, if parent is colorized
-            if (handler.isParentIncluded()) {
-                setForeground(handler.getColorByNodeType(root));
-                node.setColorized(true);
-                return this;
-            }
-        } else {
-            setForeground(NON_INCLUDE_COLOR);
-            node.setColorized(false);
-            return this;
-        }
-        if ((handler.isParentIncluded()) || 
(reverseEngineeringTree.getSelectionPath() != null)) {
-            setForeground(handler.getColorByNodeType(root));
-            node.setColorized(true);
-            return this;
-        } else {
-            if (!handler.isExistCatalogsOrSchemas()) {
-                setForeground(handler.getColorByNodeType(root));
-                node.setColorized(true);
-                return this;
-            }
-            setForeground(NON_INCLUDE_COLOR);
-            node.setColorized(false);
-            return this;
-        }
-
-    }
-
-    public void setReverseEngineeringTree(DbImportTree reverseEngineeringTree) 
{
-        this.reverseEngineeringTree = reverseEngineeringTree;
-        handler.setReverseEngineeringTree(reverseEngineeringTree);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/51289d1c/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataMapTabbedView.java
----------------------------------------------------------------------
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataMapTabbedView.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataMapTabbedView.java
index 5aa2544..ed1b6f1 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataMapTabbedView.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataMapTabbedView.java
@@ -22,6 +22,7 @@ import javax.swing.JScrollPane;
 import javax.swing.JTabbedPane;
 
 import org.apache.cayenne.modeler.ProjectController;
+import org.apache.cayenne.modeler.editor.dbimport.DbImportView;
 
 
 /**

Reply via email to