/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.tools.sessionconsole;

import java.lang.reflect.Method;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;

import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.internal.identitymaps.*;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.mappings.*;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.sessions.*;
import org.eclipse.persistence.tools.beans.*;
import org.eclipse.persistence.tools.profiler.*;
import org.eclipse.persistence.sessions.factories.*;

/**
 * Main panel for the session console. The session console is used by the
 * testing browser.
 */
public class SessionConsolePanel extends JPanel implements ActionListener,
        ItemListener, MouseListener, java.beans.PropertyChangeListener,
        ListSelectionListener {
    protected int compileCount = 0;
    protected Vector results;
    protected Vector cacheResults;
    private Session fieldSession = null;
    private JButton mBrowseProfileButton = null;
    private JMenuItem mBrowseProfileMenuItem = null;
    // SQL Page.
    private JPanel sqlPage = null;
    private JPopupMenu sqlPagePopupMenu = null;
    private JTable sqlPageTable = null;
    private JMenuItem mClearSQLMenuItem = null;
    private JMenuItem mCopySQLMenuItem = null;
    private JMenuItem mCutSQLMenuItem = null;
    private JMenuItem mDeleteSQLMenuItem = null;
    private JMenuItem mInsertSQLMenuItem = null;
    private JMenuItem mSelectSQLMenuItem = null;
    private JButton mSQLExecuteButton = null;
    private JPopupMenu mSQLMenu = null;
    private JScrollPane mSQLScrollPane = null;
    private JTextPane mSQLText = null;
    // JPQL Page.
    private JButton jpqlExecuteButton = null;
    private JTextPane jpqlText = null;

    // Cache Page.
    private JPanel cachePage = null;
    private JButton mInspectCacheButton = null;
    private JMenuItem mInspectCacheMenuItem = null;
    private JButton mClearCacheButton = null;
    private JMenuItem mClearCacheMenuItem = null;
    private JMenuItem mSQLSelectMenuItem = null;
    private JMenu mSQLTemplateMenu = null;
    private JMenuItem mSQLUpdateMenuItem = null;
    private JScrollPane cacheScrollPane = null;

    private JList mClassList = null;
    private JScrollPane mClassScrollPane = null;
    private JButton mClearButton = null;
    private JMenuItem mClearDescriptorsMenuItem = null;
    private JButton mClearLogButton = null;
    private JMenuItem cutMenuItem = null;
    private JMenuItem copyMenuItem = null;
    private JMenuItem pasteMenuItem = null;
    private JMenuItem mClearLogMenuItem = null;
    private JMenuItem mClearResultsMenuItem = null;
    private JPopupMenu mDescriptorMenu = null;
    private JMenuItem mExecuteQueryMenuItem = null;
    private ExpressionPanel mExpressionPanel = null;
    private JCheckBoxMenuItem mFullNamesMenuItem = null;
    private JMenuItem mInspectDescriptorMenuItem = null;
    private JMenuItem mInspectResultMenuItem = null;
    private JMenuItem mInspectSessionMenuItem1 = null;
    private JPopupMenu mJPopupMenu1 = null;
    private JSeparator mJSeparator4 = null;
    private JSeparator mJSeparator5 = null;
    private JSeparator mJSeparator6 = null;
    private JSeparator mJSeparator7 = null;
    private JButton mLoadProjectButton = null;
    private JTabbedPane mLogBook = null;
    private JComboBox logLevelChoice = null;
    private JButton mLoginButton = null;
    private LoginEditorPanel mLoginEditorPanel = null;
    private JPopupMenu mLoginMenu = null;
    private JMenuItem mLoginMenuItem = null;
    private JPanel mLoginPage = null;
    private JPopupMenu mLogMenu = null;
    private JButton mLogoutButton = null;
    private JMenuItem mLogoutMenuItem = null;
    private JPanel mLogPage = null;
    private JCheckBox mLogProfileCheckbox = null;
    private JCheckBoxMenuItem mLogProfileMenuItem = null;
    private JCheckBoxMenuItem mLogProfileMenuItem1 = null;
    private JScrollPane mLogScrollPane = null;
    private JSplitPane mLogSplitter = null;
    private JTextArea mLogText = null;
    private JMenuItem mPasteSQLMenuItem = null;
    private JCheckBox mProfileCheckbox = null;
    private JButton mQueryButton = null;
    private JPopupMenu mQueryMenu = null;
    private JPanel mQueryPage = null;
    private JMenuItem mResetDescriptorsMenuItem = null;
    private JPanel mResultPage = null;
    private JScrollPane mResultsScrollPane = null;
    private JTable mResultsTable = null;
    private JButton mSelectButton = null;

    // Java Page.
    private JPanel javaPage = null;
    private JScrollPane javaScrollPane = null;
    private JTextPane javaText = null;
    private JButton javaExecuteButton = null;
    private JButton javaClearButton = null;

    private JPanel mTopPanel = null;
    private JSplitPane mTopSplitPane = null;
    private JMenuItem mUpdateSQLMenuItem = null;
    private JTabbedPane mWorkspaceBook = null;

    // This attribute is used only for debugging and currently it's not
    // accessible from the ui.
    // If set to true it indicates that the DefaultConnector
    // should be substituted for JNDIConnector, and externalConnectionPooling
    // should be used.
    // Works only on Oracle, ignored on other platforms.
    private boolean shouldUseJndiConnector = false;

    /**
     * Constructor
     */
    public SessionConsolePanel() {
        super();
        initialize();
    }

    /**
     * Method to handle events for the ActionListener interface.
     */
    @Override
    public void actionPerformed(java.awt.event.ActionEvent e) {
        try {
            if (e.getSource() == getCutMenuItem()) {
                cutLog();
            }
            if (e.getSource() == getCopyMenuItem()) {
                cutLog();
            }
            if (e.getSource() == getPasteMenuItem()) {
                cutLog();
            }
            if (e.getSource() == getLoginButton()) {
                login();
            }
            if (e.getSource() == getLogoutButton()) {
                logout();
            }
            if (e.getSource() == getLoadProjectButton()) {
                loadProject();
            }
            if (e.getSource() == getClearLogButton()) {
                clearLog();
            }
            if (e.getSource() == getBrowseProfileButton()) {
                browseProfile();
            }
            if (e.getSource() == getSelectButton()) {
                selectSQL();
            }
            if (e.getSource() == getSQLExecuteButton()) {
                executeSQL();
            }
            if (e.getSource() == getJPQLExecuteButton()) {
                executeJPQL();
            }
            if (e.getSource() == getJavaExecuteButton()) {
                executeJava();
            }
            if (e.getSource() == getClearButton()) {
                clearSQL();
            }
            if (e.getSource() == getJavaClearButton()) {
                clearJava();
            }
            if (e.getSource() == getClearCacheButton()) {
                clearCache();
            }
            if (e.getSource() == getInspectCacheButton()) {
                inspectFromCache();
            }
            if (e.getSource() == getQueryButton()) {
                executeQuery();
            }
            if (e.getSource() == getClearCacheMenuItem()) {
                clearCache();
            }
            if (e.getSource() == getInspectCacheMenuItem()) {
                inspectFromCache();
            }
            if (e.getSource() == getClearResultsMenuItem()) {
                clearResults();
            }
            if (e.getSource() == getInspectResultMenuItem()) {
                inspectResult();
            }
            if (e.getSource() == getInspectDescriptorMenuItem()) {
                inspectDescriptor();
            }
            if (e.getSource() == getClearDescriptorsMenuItem()) {
                clearDescriptors();
            }
            if (e.getSource() == getResetDescriptorsMenuItem()) {
                resetDescriptors();
            }
            if (e.getSource() == getInsertSQLMenuItem()) {
                templateSQLInsert();
            }
            if (e.getSource() == getUpdateSQLMenuItem()) {
                templateSQLUpdate();
            }
            if (e.getSource() == getDeleteSQLMenuItem()) {
                templateSQLDelete();
            }
            if (e.getSource() == getSelectSQLMenuItem()) {
                templateSQLSelect();
            }
            if (e.getSource() == getSQLUpdateMenuItem()) {
                executeSQL();
            }
            if (e.getSource() == getSQLSelectMenuItem()) {
                selectSQL();
            }
            if (e.getSource() == getClearSQLMenuItem()) {
                clearSQL();
            }
            if (e.getSource() == getCutSQLMenuItem()) {
                cutSQL();
            }
            if (e.getSource() == getCopySQLMenuItem()) {
                copySQL();
            }
            if (e.getSource() == getPasteSQLMenuItem()) {
                pasteSQL();
            }
            if (e.getSource() == getLoginMenuItem()) {
                login();
            }
            if (e.getSource() == getLogoutMenuItem()) {
                logout();
            }
            if (e.getSource() == getInspectSessionMenuItem1()) {
                inspectSession();
            }
            if (e.getSource() == getExecuteQueryMenuItem()) {
                executeQuery();
            }
            if (e.getSource() == getClearLogMenuItem()) {
                clearLog();
            }
            if (e.getSource() == getBrowseProfileMenuItem()) {
                browseProfile();
            }
            if (e.getSource() == getFullNamesMenuItem()) {
                resetDescriptors();
            }
        } catch (Throwable error) {
            handleException(error);
        }
    }

    public void browseProfile() {
        if ((getSession()).isInProfile()) {
            ProfileBrowser.browseProfiles(((PerformanceProfiler) (getSession())
                    .getProfiler()).getProfiles());
        }
    }

    /**
     * Center a component with relation to another component.
     */
    public static void centerComponent(java.awt.Component component,
            java.awt.Component parent) {
        while (parent.getParent() != null) {
            parent = parent.getParent();
        }
        java.awt.Dimension parentSize = parent.getSize();
        java.awt.Dimension size = component.getSize();

        int xOffset = parent.getLocation().x;
        int yOffset = parent.getLocation().y;

        parentSize.height = parentSize.height / 2;
        parentSize.width = parentSize.width / 2;

        size.height = size.height / 2;
        size.width = size.width / 2;

        component.setLocation(parentSize.width - size.width + xOffset,
                parentSize.height - size.height + yOffset);
    }

    public void clearCache() {
        getSession().getIdentityMapAccessor().initializeIdentityMaps();
        ;
        resetCache();
    }

    public void clearDescriptors() {
        getSession().getIdentityMapAccessor().initializeIdentityMaps();
        ((AbstractSession) getSession())
                .setProject(new org.eclipse.persistence.sessions.Project());
        resetDescriptors();
    }

    public void clearLog() {
        getLogText().setText("");
    }

    public void copyLog() {
        getLogText().copy();
    }

    public void cutLog() {
        getLogText().cut();
    }

    public void pasteLog() {
        getLogText().paste();
    }

    public void clearResults() {
        setResults(new Vector());
        DefaultTableModel model = new DefaultTableModel();
        getResultsTable().setModel(model);
        getResultsTable().repaint();
    }

    public void clearSQL() {
        getSQLText().setText("");
    }

    public void clearJava() {
        getJavaText().setText("");
    }

    /**
     * connEtoC14:
     * (LogProfileCheckbox.item.itemStateChanged(java.awt.event.ItemEvent) --{@literal >}
     * SessionInspectorPanel.logProfileChanged()V)
     *
     * @param arg1
     *                java.awt.event.ItemEvent
     */
    private void connEtoC14(java.awt.event.ItemEvent arg1) {
        try {
            this.logProfileChanged();
        } catch (Throwable exception) {
            handleException(exception);
        }
    }

    /**
     * connEtoC15:
     * (ProfileCheckbox.item.itemStateChanged(java.awt.event.ItemEvent) --{@literal >}
     * SessionInspectorPanel.profileChanged()V)
     *
     * @param arg1
     *                java.awt.event.ItemEvent
     */
    private void connEtoC15(java.awt.event.ItemEvent arg1) {
        try {
            // user code begin {1}
            // user code end
            this.profileChanged();
            // user code begin {2}
            // user code end
        } catch (Throwable exception) {
            // user code begin {3}
            // user code end
            handleException(exception);
        }
    }

    /**
     * connEtoC16: (LogCheckbox.item.itemStateChanged(java.awt.event.ItemEvent)
     * --{@literal >} SessionInspectorPanel.loggingChanged()V)
     *
     * @param arg1
     *                java.awt.event.ItemEvent
     */
    private void connEtoC16(java.awt.event.ItemEvent arg1) {
        try {
            // user code begin {1}
            // user code end
            this.loggingChanged();
            // user code begin {2}
            // user code end
        } catch (Throwable exception) {
            // user code begin {3}
            // user code end
            handleException(exception);
        }
    }

    /**
     * connEtoC18: (SQLText.mouse.mouseReleased(java.awt.event.MouseEvent) --{@literal >}
     * SessionInspectorPanel.genericPopupDisplay(Ljava.awt.event.MouseEvent;LJPopupMenu;)V)
     *
     * @param arg1
     *                java.awt.event.MouseEvent
     */
    private void connEtoC18(java.awt.event.MouseEvent arg1) {
        try {
            // user code begin {1}
            // user code end
            this.genericPopupDisplay(arg1, getSQLMenu());
            // user code begin {2}
            // user code end
        } catch (Throwable exception) {
            // user code begin {3}
            // user code end
            handleException(exception);
        }
    }

    /**
     * connEtoC19: (CacheTable.mouse.mouseReleased(java.awt.event.MouseEvent)
     * --{@literal >}
     * SessionInspectorPanel.genericPopupDisplay(Ljava.awt.event.MouseEvent;LJPopupMenu;)V)
     *
     * @param arg1
     *                java.awt.event.MouseEvent
     */
    private void connEtoC19(java.awt.event.MouseEvent arg1) {
        try {
            this.genericPopupDisplay(arg1, getCachePopupMenu());
        } catch (Throwable exception) {
            handleException(exception);
        }
    }

    /**
     * connEtoC20:
     * (ResultsScrollPane.mouse.mouseReleased(java.awt.event.MouseEvent) --{@literal >}
     * SessionInspectorPanel.genericPopupDisplay(Ljava.awt.event.MouseEvent;LJPopupMenu;)V)
     *
     * @param arg1
     *                java.awt.event.MouseEvent
     */
    private void connEtoC20(java.awt.event.MouseEvent arg1) {
        try {
            // user code begin {1}
            // user code end
            this.genericPopupDisplay(arg1, getJPopupMenu1());
            // user code begin {2}
            // user code end
        } catch (Throwable exception) {
            // user code begin {3}
            // user code end
            handleException(exception);
        }
    }

    /**
     * connEtoC21: (ClassList.mouse.mouseReleased(java.awt.event.MouseEvent) --{@literal >}
     * SessionInspectorPanel.genericPopupDisplay(Ljava.awt.event.MouseEvent;LJPopupMenu;)V)
     *
     * @param arg1
     *                java.awt.event.MouseEvent
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    void connEtoC21(java.awt.event.MouseEvent arg1) {
        try {
            // user code begin {1}
            // user code end
            this.genericPopupDisplay(arg1, getDescriptorMenu());
            // user code begin {2}
            // user code end
        } catch (Throwable exception) {
            // user code begin {3}
            // user code end
            handleException(exception);
        }
    }

    /**
     * connEtoC3:
     * (ClassList.listSelection.valueChanged(event.ListSelectionEvent) --{@literal >}
     * SessionInspectorPanel.resetCache()V)
     *
     * @param arg1
     *                event.ListSelectionEvent
     */
    private void connEtoC3(ListSelectionEvent arg1) {
        try {
            this.descriptorChanged();
        } catch (Throwable exception) {
            handleException(exception);
        }
    }

    /**
     * connEtoC40: (QueryPage.mouse.mouseReleased(java.awt.event.MouseEvent) --{@literal >}
     * SessionInspectorPanel.genericPopupDisplay(Ljava.awt.event.MouseEvent;LJPopupMenu;)V)
     *
     * @param arg1
     *                java.awt.event.MouseEvent
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    void connEtoC40(java.awt.event.MouseEvent arg1) {
        try {
            // user code begin {1}
            // user code end
            this.genericPopupDisplay(arg1, getQueryMenu());
            // user code begin {2}
            // user code end
        } catch (Throwable exception) {
            // user code begin {3}
            // user code end
            handleException(exception);
        }
    }

    /**
     * connEtoC41: (LogText.mouse.mouseReleased(java.awt.event.MouseEvent) --{@literal >}
     * SessionInspectorPanel.genericPopupDisplay(Ljava.awt.event.MouseEvent;LJPopupMenu;)V)
     *
     * @param arg1
     *                java.awt.event.MouseEvent
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    void connEtoC41(java.awt.event.MouseEvent arg1) {
        try {
            // user code begin {1}
            // user code end
            this.genericPopupDisplay(arg1, getLogMenu());
            // user code begin {2}
            // user code end
        } catch (Throwable exception) {
            // user code begin {3}
            // user code end
            handleException(exception);
        }
    }

    /**
     * connEtoC42: (LoginPage.mouse.mouseReleased(java.awt.event.MouseEvent) --{@literal >}
     * SessionInspectorPanel.genericPopupDisplay(Ljava.awt.event.MouseEvent;LJPopupMenu;)V)
     *
     * @param arg1
     *                java.awt.event.MouseEvent
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    void connEtoC42(java.awt.event.MouseEvent arg1) {
        try {
            // user code begin {1}
            // user code end
            this.genericPopupDisplay(arg1, getLoginMenu());
            // user code begin {2}
            // user code end
        } catch (Throwable exception) {
            // user code begin {3}
            // user code end
            handleException(exception);
        }
    }

    /**
     * connPtoP1SetTarget: (BrowseProfileMenuItem.enabled {@literal <}--{@literal >}
     * BrowseProfileButton.enabled)
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    void connPtoP1SetTarget() {
        /* Set the target from the source */
        try {
            getBrowseProfileButton().setEnabled(
                    getBrowseProfileMenuItem().isEnabled());
            // user code begin {1}
            // user code end
        } catch (Throwable exception) {
            // user code begin {3}
            // user code end
            handleException(exception);
        }
    }

    /**
     * connPtoP2SetTarget: (LogProfileMenuItem.selected {@literal <}--{@literal >}
     * LogProfileCheckbox.selected)
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    void connPtoP2SetTarget() {
        /* Set the target from the source */
        try {
            getLogProfileCheckbox().setSelected(
                    getLogProfileMenuItem().isSelected());
            // user code begin {1}
            // user code end
        } catch (Throwable exception) {
            // user code begin {3}
            // user code end
            handleException(exception);
        }
    }

    /**
     * connPtoP3SetTarget: (ProfileCheckbox.selected {@literal <}--{@literal >}
     * LogProfileMenuItem1.selected)
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    void connPtoP3SetTarget() {
        /* Set the target from the source */
        try {
            getLogProfileMenuItem1().setSelected(
                    getProfileCheckbox().isSelected());
            // user code begin {1}
            // user code end
        } catch (Throwable exception) {
            // user code begin {3}
            // user code end
            handleException(exception);
        }
    }

    /**
     * connPtoP4SetTarget: (LogSQLMenuItem.selected {@literal <}--{@literal >} LogCheckbox.selected)
     */
    private void connPtoP4SetTarget() {
        try {
            getLogLevelChoice().setSelectedIndex(
                    getSession().getSessionLog().getLevel());
        } catch (Throwable exception) {
            handleException(exception);
        }
    }

    public void copySQL() {
        getSQLText().copy();
    }

    public void createTables() {
        // //Helper.toDo("table creators");
    }

    public void cutSQL() {
        getSQLText().cut();
    }

    public void descriptorChanged() {
        resetCache();
        ClassInfo info = (ClassInfo) getClassList().getSelectedValue();
        if (info != null) {
            getExpressionPanel().setDescriptor(info.descriptor);
        }
    }

    public void executeQuery() {
        showBusyCursor();
        try {
            ClassInfo info = (ClassInfo) getClassList().getSelectedValue();
            if (info == null) {
                return;
            }

            ReadAllQuery query = new ReadAllQuery(getExpressionPanel()
                    .getDescriptor().getJavaClass());
            query.setSelectionCriteria(getExpressionPanel().getExpression());

            setResultObjects((Vector) getSession().executeQuery(query),
                    getExpressionPanel().getDescriptor());

            getLogBook().setSelectedComponent(getResultPage());
        } finally {
            showNormalCursor();
        }
    }

    public void executeSQL() {
        showBusyCursor();
        try {
            String sql = getSQLText().getSelectedText();
            if ((sql == null) || (sql.length() == 0)) {
                return;
            }
            getSession().executeNonSelectingCall(new SQLCall(sql));
        } finally {
            showNormalCursor();
        }
    }

    public void executeJPQL() {
        showBusyCursor();
        try {
            getSession().getProject().getJPQLParseCache().getCache().clear();

            String jpql = getJPQLText().getSelectedText();
            if ((jpql == null) || (jpql.length() == 0)) {
                return;
            }
            DatabaseQuery query = ((AbstractSession)getSession()).getQueryBuilder().buildQuery(jpql, (AbstractSession)getSession());
            if (query.isReadQuery()) {
                setResultReports((Vector) getSession().executeQuery(query));
                getLogBook().setSelectedComponent(getResultPage());
            } else {
                getSession().executeQuery(query);
            }
        } finally {
            showNormalCursor();
        }
    }

    /**
     * Execute the selected Java code. This is done through compiling and
     * executing the code through sun.tools. TopLink imports are auto defined,
     * "session" variable can be used for the connected session.
     */
    public void executeJava() {
        showBusyCursor();
        try {
            String java = getJavaText().getSelectedText();
            if ((java == null) || (java.length() == 0)) {
                return;
            }

            try {
                compileCount++;
                String className = "JavaCode" + compileCount;
                String[] source = { className + ".java" };
                File file = new File(className + ".java");
                file.createNewFile();
                FileWriter writer = new FileWriter(file);
                writer.write("import java.util.*;\n");
                writer.write("import org.eclipse.persistence.sessions.*;\n");
                writer.write("import org.eclipse.persistence.expressions.*;\n");
                writer.write("import org.eclipse.persistence.queries.*;\n");
                writer.write("public class " + className + " {\n");
                writer.write("public Session session;\n");
                writer.write("public Object exec() {\n");
                writer.write(java);
                if (java.indexOf("return") < 0) {
                    writer.write("return \"success\";\n");
                }
                writer.write("}\n");
                writer.write("}\n");
                writer.flush();
                writer.close();

                // done reflectively to remove dependency on tools jar
                Object[] params = new Object[1];
                params[0] = source;
                Class mainClass = Class.forName("com.sun.tools.javac.Main");
                Class[] parameterTypes = new Class[1];
                parameterTypes[0] = String[].class;
                Method method = mainClass.getMethod("compile", parameterTypes);
                int result = (Integer) method.invoke(null, params);
                if (result != 0) {
                    throw new RuntimeException(
                            "Java code compile failed. This could either be a legitimate compile "
                                    + "failure, or could result if you do not have the tools.jar from your JDK on the classpath.");
                }
                Class newClass = Class.forName(className);
                Object newInstance = newClass.getConstructor().newInstance();
                newClass.getField("session").set(newInstance, getSession());
                Object value;
                try {
                    value = newClass.getMethod("exec", (Class[]) null).invoke(
                            newInstance, (Object[]) null);
                } catch (java.lang.reflect.InvocationTargetException exception) {
                    throw exception.getCause();
                }
                inspect(value);
            } catch (Throwable exception) {
                if (exception instanceof RuntimeException) {
                    throw (RuntimeException) exception;
                } else {
                    throw new RuntimeException(exception.toString());
                }
            }
        } finally {
            showNormalCursor();
        }
    }

    public void genericPopupDisplay(MouseEvent mouseEvent, JPopupMenu menu) {
        if (mouseEvent.isPopupTrigger()) {
            menu.show(mouseEvent.getComponent(), mouseEvent.getX(), mouseEvent
                    .getY());
        }
    }

    /**
     * Return the BrowseProfileButton property value.
     *
     * @return JButton
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JButton getBrowseProfileButton() {
        if (mBrowseProfileButton == null) {
            try {
                mBrowseProfileButton = new JButton();
                mBrowseProfileButton.setName("BrowseProfileButton");
                mBrowseProfileButton.setText("Browse Profile");
                mBrowseProfileButton
                        .setBackground(java.awt.SystemColor.control);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mBrowseProfileButton;
    }

    /**
     * Return the BrowseProfileMenuItem property value.
     *
     * @return JMenuItem
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JMenuItem getBrowseProfileMenuItem() {
        if (mBrowseProfileMenuItem == null) {
            try {
                mBrowseProfileMenuItem = new JMenuItem();
                mBrowseProfileMenuItem.setName("BrowseProfileMenuItem");
                mBrowseProfileMenuItem.setText("Browse Profile");
                mBrowseProfileMenuItem.setBackground(java.awt.SystemColor.menu);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mBrowseProfileMenuItem;
    }

    private JPanel getSQLPage() {
        if (sqlPage == null) {
            try {
                sqlPage = new JPanel();
                sqlPage.setName("SQL");
                sqlPage.setLayout(new java.awt.GridBagLayout());
                sqlPage.setBackground(java.awt.SystemColor.control);

                java.awt.GridBagConstraints constraintsSQLExecuteButton = new java.awt.GridBagConstraints();
                constraintsSQLExecuteButton.gridx = 1;
                constraintsSQLExecuteButton.gridy = 1;
                constraintsSQLExecuteButton.insets = new java.awt.Insets(2, 2,
                        2, 2);
                getSQLPage().add(getSQLExecuteButton(),
                        constraintsSQLExecuteButton);

                java.awt.GridBagConstraints constraintsClearButton = new java.awt.GridBagConstraints();
                constraintsClearButton.gridx = 2;
                constraintsClearButton.gridy = 1;
                constraintsClearButton.insets = new java.awt.Insets(2, 2, 2, 2);
                getSQLPage().add(getClearButton(), constraintsClearButton);

                java.awt.GridBagConstraints constraintsSelectButton = new java.awt.GridBagConstraints();
                constraintsSelectButton.gridx = 0;
                constraintsSelectButton.gridy = 1;
                constraintsSelectButton.insets = new java.awt.Insets(2, 2, 2, 2);
                getSQLPage().add(getSelectButton(), constraintsSelectButton);

                java.awt.GridBagConstraints constraintsSQLScrollPane = new java.awt.GridBagConstraints();
                constraintsSQLScrollPane.gridx = 0;
                constraintsSQLScrollPane.gridy = 0;
                constraintsSQLScrollPane.gridwidth = 5;
                constraintsSQLScrollPane.fill = java.awt.GridBagConstraints.BOTH;
                constraintsSQLScrollPane.weightx = 1.0;
                constraintsSQLScrollPane.weighty = 1.0;
                constraintsSQLScrollPane.insets = new java.awt.Insets(0, 0, 2,
                        0);
                getSQLPage().add(getSQLScrollPane(), constraintsSQLScrollPane);
            } catch (Throwable exception) {
                handleException(exception);
            }
        }
        return sqlPage;
    }

    private JPanel getJPQLPage() {
        JPanel page = new JPanel();
        page.setName("JPQL");
        page.setLayout(new GridBagLayout());
        page.setBackground(SystemColor.control);

        GridBagConstraints constraints = new GridBagConstraints();
        constraints.gridx = 1;
        constraints.gridy = 1;
        constraints.insets = new Insets(2, 2, 2, 2);
        page.add(getJPQLExecuteButton(), constraints);

        constraints = new GridBagConstraints();
        constraints.gridx = 0;
        constraints.gridy = 0;
        constraints.gridwidth = 5;
        constraints.fill = GridBagConstraints.BOTH;
        constraints.weightx = 1.0;
        constraints.weighty = 1.0;
        constraints.insets = new Insets(0, 0, 2, 0);
        page.add(getJPQLScrollPane(), constraints);
        return page;
    }

    private JPanel getJavaPage() {
        if (javaPage == null) {
            try {
                javaPage = new JPanel();
                javaPage.setName("Java");
                javaPage.setLayout(new GridBagLayout());
                javaPage.setBackground(SystemColor.control);

                GridBagConstraints constraints = new GridBagConstraints();
                constraints.gridx = 1;
                constraints.gridy = 1;
                constraints.insets = new Insets(2, 2, 2, 2);
                getJavaPage().add(getJavaExecuteButton(), constraints);

                constraints = new GridBagConstraints();
                constraints.gridx = 2;
                constraints.gridy = 1;
                constraints.insets = new Insets(2, 2, 2, 2);
                getJavaPage().add(getJavaClearButton(), constraints);

                constraints = new GridBagConstraints();
                constraints.gridx = 0;
                constraints.gridy = 0;
                constraints.gridwidth = 5;
                constraints.fill = GridBagConstraints.BOTH;
                constraints.weightx = 1.0;
                constraints.weighty = 1.0;
                constraints.insets = new Insets(0, 0, 2, 0);
                getJavaPage().add(getJavaScrollPane(), constraints);
            } catch (Throwable exception) {
                handleException(exception);
            }
        }
        return javaPage;
    }

    /**
     * Return the SQLPage property value.
     *
     * @return JPanel
     */
    private JPanel getCachePage() {
        if (cachePage == null) {
            try {
                cachePage = new JPanel();
                cachePage.setName("CachePage");
                cachePage.setLayout(new GridBagLayout());
                cachePage.setBackground(SystemColor.control);

                GridBagConstraints constraintsClearCacheButton = new GridBagConstraints();
                constraintsClearCacheButton.gridx = 0;
                constraintsClearCacheButton.gridy = 1;
                constraintsClearCacheButton.insets = new Insets(2, 2, 2, 2);
                getCachePage().add(getClearCacheButton(),
                        constraintsClearCacheButton);

                GridBagConstraints constraintsCacheScrollPane = new GridBagConstraints();
                constraintsCacheScrollPane.gridx = 0;
                constraintsCacheScrollPane.gridy = 0;
                constraintsCacheScrollPane.gridwidth = 6;
                constraintsCacheScrollPane.fill = GridBagConstraints.BOTH;
                constraintsCacheScrollPane.weightx = 1.0;
                constraintsCacheScrollPane.weighty = 1.0;
                constraintsCacheScrollPane.insets = new Insets(0, 0, 2, 0);
                getCachePage().add(getCacheScrollPane(),
                        constraintsCacheScrollPane);

                GridBagConstraints constraintsInspectCacheButton = new GridBagConstraints();
                constraintsInspectCacheButton.gridx = 1;
                constraintsInspectCacheButton.gridy = 1;
                constraintsInspectCacheButton.insets = new Insets(2, 2, 2, 2);
                getCachePage().add(getInspectCacheButton(),
                        constraintsInspectCacheButton);
            } catch (Throwable exception) {
                handleException(exception);
            }
        }
        return cachePage;
    }

    /**
     * Return the CachePopupMenu property value.
     *
     * @return JPopupMenu
     */
    private JPopupMenu getCachePopupMenu() {
        if (sqlPagePopupMenu == null) {
            try {
                sqlPagePopupMenu = new JPopupMenu();
                sqlPagePopupMenu.setName("CachePopupMenu");
                sqlPagePopupMenu.add(getClearCacheMenuItem());
                sqlPagePopupMenu.add(getInspectCacheMenuItem());
            } catch (Throwable exception) {
                handleException(exception);
            }
        }
        return sqlPagePopupMenu;
    }

    public Vector getCacheResults() {
        return cacheResults;
    }

    /**
     * Return the CacheScrollPane property value.
     *
     * @return JScrollPane
     */
    private JScrollPane getCacheScrollPane() {
        if (cacheScrollPane == null) {
            try {
                cacheScrollPane = new JScrollPane();
                cacheScrollPane.setName("CacheScrollPane");
                getCacheScrollPane().setViewportView(getCacheTable());
            } catch (Throwable exception) {
                handleException(exception);
            }
        }
        return cacheScrollPane;
    }

    /**
     * Return the CacheTable property value.
     *
     * @return JTable
     */
    private JTable getCacheTable() {
        if (sqlPageTable == null) {
            try {
                sqlPageTable = new JTable();
                sqlPageTable.setName("CacheTable");
                getCacheScrollPane().setColumnHeaderView(
                        sqlPageTable.getTableHeader());
                sqlPageTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
                sqlPageTable.setPreferredSize(new Dimension(600, 300));
                sqlPageTable.setBounds(0, 0, 583, 370);
                sqlPageTable.setPreferredScrollableViewportSize(new Dimension(
                        600, 300));
            } catch (Throwable exception) {
                handleException(exception);
            }
        }
        return sqlPageTable;
    }

    /**
     * Return the ClassList property value.
     *
     * @return JList
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JList getClassList() {
        if (mClassList == null) {
            try {
                mClassList = new JList();
                mClassList.setName("ClassList");
                mClassList
                        .setBorder(new javax.swing.plaf.basic.BasicBorders.MarginBorder());
                mClassList.setBounds(0, 0, 160, 428);
                mClassList.setMinimumSize(new Dimension(1, 1));
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mClassList;
    }

    /**
     * Return the ClassScrollPane property value.
     *
     * @return JScrollPane
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JScrollPane getClassScrollPane() {
        if (mClassScrollPane == null) {
            try {
                mClassScrollPane = new JScrollPane();
                mClassScrollPane.setName("ClassScrollPane");
                mClassScrollPane.setMaximumSize(new Dimension(0, 0));
                mClassScrollPane.setPreferredSize(new Dimension(120, 0));
                mClassScrollPane.setMinimumSize(new Dimension(100, 0));
                getClassScrollPane().setViewportView(getClassList());
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mClassScrollPane;
    }

    /**
     * Return the ClearButton property value.
     *
     * @return JButton
     */
    private JButton getClearButton() {
        if (mClearButton == null) {
            try {
                mClearButton = new JButton();
                mClearButton.setName("ClearButton");
                mClearButton.setText("Clear");
                mClearButton.setBackground(SystemColor.control);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mClearButton;
    }

    private JButton getJavaClearButton() {
        if (javaClearButton == null) {
            try {
                javaClearButton = new JButton();
                javaClearButton.setName("JavaClearButton");
                javaClearButton.setText("Clear");
                javaClearButton.setBackground(SystemColor.control);
            } catch (Throwable exception) {
                handleException(exception);
            }
        }
        return javaClearButton;
    }

    /**
     * Return the ClearCacheButton property value.
     *
     * @return JButton
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JButton getClearCacheButton() {
        if (mClearCacheButton == null) {
            try {
                mClearCacheButton = new JButton();
                mClearCacheButton.setName("ClearCacheButton");
                mClearCacheButton.setText("Clear Cache");
                mClearCacheButton.setBackground(SystemColor.control);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mClearCacheButton;
    }

    /**
     * Return the ClearCacheMenuItem property value.
     *
     * @return JMenuItem
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JMenuItem getClearCacheMenuItem() {
        if (mClearCacheMenuItem == null) {
            try {
                mClearCacheMenuItem = new JMenuItem();
                mClearCacheMenuItem.setName("ClearCacheMenuItem");
                mClearCacheMenuItem.setText("Clear Cache");
                mClearCacheMenuItem.setBackground(SystemColor.menu);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mClearCacheMenuItem;
    }

    /**
     * Return the ClearDescriptorsMenuItem property value.
     *
     * @return JMenuItem
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JMenuItem getClearDescriptorsMenuItem() {
        if (mClearDescriptorsMenuItem == null) {
            try {
                mClearDescriptorsMenuItem = new JMenuItem();
                mClearDescriptorsMenuItem.setName("ClearDescriptorsMenuItem");
                mClearDescriptorsMenuItem.setText("Clear Descriptors");
                mClearDescriptorsMenuItem.setBackground(SystemColor.menu);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mClearDescriptorsMenuItem;
    }

    /**
     * Return the ClearLogButton property value.
     *
     * @return JButton
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JButton getClearLogButton() {
        if (mClearLogButton == null) {
            try {
                mClearLogButton = new JButton();
                mClearLogButton.setName("ClearLogButton");
                mClearLogButton.setText("Clear");
                mClearLogButton.setBackground(SystemColor.control);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mClearLogButton;
    }

    /**
     * Return the ClearLogMenuItem property value.
     *
     * @return JMenuItem
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JMenuItem getClearLogMenuItem() {
        if (mClearLogMenuItem == null) {
            try {
                mClearLogMenuItem = new JMenuItem();
                mClearLogMenuItem.setName("ClearLogMenuItem");
                mClearLogMenuItem.setText("Clear Log");
                mClearLogMenuItem.setBackground(SystemColor.menu);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mClearLogMenuItem;
    }

    private JMenuItem getCutMenuItem() {
        if (cutMenuItem == null) {
            try {
                cutMenuItem = new JMenuItem();
                cutMenuItem.setName("CutMenuItem");
                cutMenuItem.setText("Cut");
                cutMenuItem.setBackground(SystemColor.menu);
            } catch (Throwable exception) {
                handleException(exception);
            }
        }
        return cutMenuItem;
    }

    private JMenuItem getCopyMenuItem() {
        if (copyMenuItem == null) {
            try {
                copyMenuItem = new JMenuItem();
                copyMenuItem.setName("CopyMenuItem");
                copyMenuItem.setText("Copy");
                copyMenuItem.setBackground(SystemColor.menu);
            } catch (Throwable exception) {
                handleException(exception);
            }
        }
        return copyMenuItem;
    }

    private JMenuItem getPasteMenuItem() {
        if (pasteMenuItem == null) {
            try {
                pasteMenuItem = new JMenuItem();
                pasteMenuItem.setName("PasteMenuItem");
                pasteMenuItem.setText("Paste");
                pasteMenuItem.setBackground(SystemColor.menu);
            } catch (Throwable exception) {
                handleException(exception);
            }
        }
        return pasteMenuItem;
    }

    /**
     * Return the ClearResultsMenuItem property value.
     *
     * @return JMenuItem
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JMenuItem getClearResultsMenuItem() {
        if (mClearResultsMenuItem == null) {
            try {
                mClearResultsMenuItem = new JMenuItem();
                mClearResultsMenuItem.setName("ClearResultsMenuItem");
                mClearResultsMenuItem.setText("Clear Results");
                mClearResultsMenuItem.setBackground(SystemColor.menu);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mClearResultsMenuItem;
    }

    /**
     * Return the ClearSQLMenuItem property value.
     *
     * @return JMenuItem
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JMenuItem getClearSQLMenuItem() {
        if (mClearSQLMenuItem == null) {
            try {
                mClearSQLMenuItem = new JMenuItem();
                mClearSQLMenuItem.setName("ClearSQLMenuItem");
                mClearSQLMenuItem.setText("Clear SQL");
                mClearSQLMenuItem.setBackground(SystemColor.menu);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mClearSQLMenuItem;
    }

    /**
     * Return the CopySQLMenuItem property value.
     *
     * @return JMenuItem
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JMenuItem getCopySQLMenuItem() {
        if (mCopySQLMenuItem == null) {
            try {
                mCopySQLMenuItem = new JMenuItem();
                mCopySQLMenuItem.setName("CopySQLMenuItem");
                mCopySQLMenuItem.setText("Copy");
                mCopySQLMenuItem.setBackground(SystemColor.menu);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mCopySQLMenuItem;
    }

    /**
     * Return the CutSQLMenuItem property value.
     *
     * @return JMenuItem
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JMenuItem getCutSQLMenuItem() {
        if (mCutSQLMenuItem == null) {
            try {
                mCutSQLMenuItem = new JMenuItem();
                mCutSQLMenuItem.setName("CutSQLMenuItem");
                mCutSQLMenuItem.setText("Cut");
                mCutSQLMenuItem.setBackground(SystemColor.menu);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mCutSQLMenuItem;
    }

    /**
     * Return the DeleteSQLMenuItem property value.
     *
     * @return JMenuItem
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JMenuItem getDeleteSQLMenuItem() {
        if (mDeleteSQLMenuItem == null) {
            try {
                mDeleteSQLMenuItem = new JMenuItem();
                mDeleteSQLMenuItem.setName("DeleteSQLMenuItem");
                mDeleteSQLMenuItem.setText("Delete SQL");
                mDeleteSQLMenuItem.setBackground(SystemColor.menu);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mDeleteSQLMenuItem;
    }

    /**
     * Return the DescriptorMenu property value.
     *
     * @return JPopupMenu
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JPopupMenu getDescriptorMenu() {
        if (mDescriptorMenu == null) {
            try {
                mDescriptorMenu = new JPopupMenu();
                mDescriptorMenu.setName("DescriptorMenu");
                mDescriptorMenu.add(getResetDescriptorsMenuItem());
                mDescriptorMenu.add(getClearDescriptorsMenuItem());
                mDescriptorMenu.add(getFullNamesMenuItem());
                mDescriptorMenu.add(getInspectDescriptorMenuItem());
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mDescriptorMenu;
    }

    /**
     * Return the ExecuteQueryMenuItem property value.
     *
     * @return JMenuItem
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JMenuItem getExecuteQueryMenuItem() {
        if (mExecuteQueryMenuItem == null) {
            try {
                mExecuteQueryMenuItem = new JMenuItem();
                mExecuteQueryMenuItem.setName("ExecuteQueryMenuItem");
                mExecuteQueryMenuItem.setText("Execute Query");
                mExecuteQueryMenuItem.setBackground(SystemColor.menu);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mExecuteQueryMenuItem;
    }

    /**
     * Return the ExpressionPanel property value.
     *
     * @return ExpressionPanel
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    org.eclipse.persistence.tools.beans.ExpressionPanel getExpressionPanel() {
        if (mExpressionPanel == null) {
            try {
                mExpressionPanel = new org.eclipse.persistence.tools.beans.ExpressionPanel();
                mExpressionPanel.setName("ExpressionPanel");
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mExpressionPanel;
    }

    /**
     * Return the FullNamesMenuItem property value.
     *
     * @return JCheckBoxMenuItem
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JCheckBoxMenuItem getFullNamesMenuItem() {
        if (mFullNamesMenuItem == null) {
            try {
                mFullNamesMenuItem = new JCheckBoxMenuItem();
                mFullNamesMenuItem.setName("FullNamesMenuItem");
                mFullNamesMenuItem.setText("Display Package Names");
                mFullNamesMenuItem.setBackground(SystemColor.control);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mFullNamesMenuItem;
    }

    /**
     * Return the InsertSQLMenuItem property value.
     *
     * @return JMenuItem
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JMenuItem getInsertSQLMenuItem() {
        if (mInsertSQLMenuItem == null) {
            try {
                mInsertSQLMenuItem = new JMenuItem();
                mInsertSQLMenuItem.setName("InsertSQLMenuItem");
                mInsertSQLMenuItem.setText("Insert SQL");
                mInsertSQLMenuItem.setBackground(SystemColor.menu);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mInsertSQLMenuItem;
    }

    /**
     * Return the InspectCacheButton property value.
     *
     * @return JButton
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JButton getInspectCacheButton() {
        if (mInspectCacheButton == null) {
            try {
                mInspectCacheButton = new JButton();
                mInspectCacheButton.setName("InspectCacheButton");
                mInspectCacheButton.setText("Inspect");
                mInspectCacheButton.setBackground(SystemColor.control);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mInspectCacheButton;
    }

    /**
     * Return the InspectCacheMenuItem property value.
     *
     * @return JMenuItem
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JMenuItem getInspectCacheMenuItem() {
        if (mInspectCacheMenuItem == null) {
            try {
                mInspectCacheMenuItem = new JMenuItem();
                mInspectCacheMenuItem.setName("InspectCacheMenuItem");
                mInspectCacheMenuItem.setText("Inspect Cache");
                mInspectCacheMenuItem.setBackground(SystemColor.menu);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mInspectCacheMenuItem;
    }

    /**
     * Return the InspectDescriptorMenuItem property value.
     *
     * @return JMenuItem
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JMenuItem getInspectDescriptorMenuItem() {
        if (mInspectDescriptorMenuItem == null) {
            try {
                mInspectDescriptorMenuItem = new JMenuItem();
                mInspectDescriptorMenuItem.setName("InspectDescriptorMenuItem");
                mInspectDescriptorMenuItem.setText("Inspect Descriptor");
                mInspectDescriptorMenuItem.setBackground(SystemColor.menu);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mInspectDescriptorMenuItem;
    }

    /**
     * Return the InspectResultMenuItem property value.
     *
     * @return JMenuItem
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JMenuItem getInspectResultMenuItem() {
        if (mInspectResultMenuItem == null) {
            try {
                mInspectResultMenuItem = new JMenuItem();
                mInspectResultMenuItem.setName("InspectResultMenuItem");
                mInspectResultMenuItem.setText("Inspect Result");
                mInspectResultMenuItem.setBackground(SystemColor.menu);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mInspectResultMenuItem;
    }

    /**
     * Return the InspectSessionMenuItem1 property value.
     *
     * @return JMenuItem
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JMenuItem getInspectSessionMenuItem1() {
        if (mInspectSessionMenuItem1 == null) {
            try {
                mInspectSessionMenuItem1 = new JMenuItem();
                mInspectSessionMenuItem1.setName("InspectSessionMenuItem1");
                mInspectSessionMenuItem1.setText("Inspect Session");
                mInspectSessionMenuItem1.setBackground(SystemColor.menu);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mInspectSessionMenuItem1;
    }

    /**
     * Return the JPopupMenu1 property value.
     *
     * @return JPopupMenu
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JPopupMenu getJPopupMenu1() {
        if (mJPopupMenu1 == null) {
            try {
                mJPopupMenu1 = new JPopupMenu();
                mJPopupMenu1.setName("JPopupMenu1");
                mJPopupMenu1.add(getClearResultsMenuItem());
                mJPopupMenu1.add(getInspectResultMenuItem());
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mJPopupMenu1;
    }

    /**
     * Return the JSeparator4 property value.
     *
     * @return JSeparator
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JSeparator getJSeparator4() {
        if (mJSeparator4 == null) {
            try {
                mJSeparator4 = new JSeparator();
                mJSeparator4.setName("JSeparator4");
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mJSeparator4;
    }

    /**
     * Return the JSeparator5 property value.
     *
     * @return JSeparator
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JSeparator getJSeparator5() {
        if (mJSeparator5 == null) {
            try {
                mJSeparator5 = new JSeparator();
                mJSeparator5.setName("JSeparator5");
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mJSeparator5;
    }

    /**
     * Return the JSeparator6 property value.
     *
     * @return JSeparator
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JSeparator getJSeparator6() {
        if (mJSeparator6 == null) {
            try {
                mJSeparator6 = new JSeparator();
                mJSeparator6.setName("JSeparator6");
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mJSeparator6;
    }

    /**
     * Return the JSeparator7 property value.
     *
     * @return JSeparator
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JSeparator getJSeparator7() {
        if (mJSeparator7 == null) {
            try {
                mJSeparator7 = new JSeparator();
                mJSeparator7.setName("JSeparator7");
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mJSeparator7;
    }

    /**
     * Return the LoadProjectButton property value.
     *
     * @return JButton
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JButton getLoadProjectButton() {
        if (mLoadProjectButton == null) {
            try {
                mLoadProjectButton = new JButton();
                mLoadProjectButton.setName("LoadProjectButton");
                mLoadProjectButton.setText("Load Project...");
                mLoadProjectButton.setBackground(SystemColor.control);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mLoadProjectButton;
    }

    /**
     * Return the LogBook property value.
     *
     * @return JTabbedPane
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JTabbedPane getLogBook() {
        if (mLogBook == null) {
            try {
                mLogBook = new JTabbedPane();
                mLogBook.setName("LogBook");
                mLogBook.insertTab("Log", null, getLogPage(), null, 0);
                mLogBook.setBackgroundAt(0, SystemColor.control);
                mLogBook
                        .insertTab("ResultPage", null, getResultPage(), null, 1);
                mLogBook.setBackgroundAt(1, SystemColor.control);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mLogBook;
    }

    private JComboBox getLogLevelChoice() {
        if (logLevelChoice == null) {
            try {
                logLevelChoice = new JComboBox();
                logLevelChoice.setName("LogLevelChoice");
                logLevelChoice.addItem("All");
                logLevelChoice.addItem("Finest");
                logLevelChoice.addItem("Finer");
                logLevelChoice.addItem("Fine");
                logLevelChoice.addItem("Config");
                logLevelChoice.addItem("Info");
                logLevelChoice.addItem("Warning");
                logLevelChoice.addItem("Sever");
                logLevelChoice.addItem("None");
                logLevelChoice.setSelectedItem("None");
            } catch (Throwable exception) {
                handleException(exception);
            }
        }
        return logLevelChoice;
    }

    /**
     * Return the LoginButton property value.
     *
     * @return JButton
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JButton getLoginButton() {
        if (mLoginButton == null) {
            try {
                mLoginButton = new JButton();
                mLoginButton.setName("LoginButton");
                mLoginButton.setText("Login");
                mLoginButton.setBackground(SystemColor.control);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mLoginButton;
    }

    public LoginEditorPanel getLoginEditor() {
        return getLoginEditorPanel();
    }

    /**
     * Return the LoginEditorPanel property value.
     *
     * @return LoginEditorPanel
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    LoginEditorPanel getLoginEditorPanel() {
        if (mLoginEditorPanel == null) {
            try {
                mLoginEditorPanel = new org.eclipse.persistence.tools.sessionconsole.LoginEditorPanel();
                mLoginEditorPanel.setName("LoginEditorPanel");
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mLoginEditorPanel;
    }

    /**
     * Return the LoginMenu property value.
     *
     * @return JPopupMenu
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JPopupMenu getLoginMenu() {
        if (mLoginMenu == null) {
            try {
                mLoginMenu = new JPopupMenu();
                mLoginMenu.setName("LoginMenu");
                mLoginMenu.add(getLoginMenuItem());
                mLoginMenu.add(getLogoutMenuItem());
                mLoginMenu.add(getInspectSessionMenuItem1());
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mLoginMenu;
    }

    /**
     * Return the LoginMenuItem property value.
     *
     * @return JMenuItem
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JMenuItem getLoginMenuItem() {
        if (mLoginMenuItem == null) {
            try {
                mLoginMenuItem = new JMenuItem();
                mLoginMenuItem.setName("LoginMenuItem");
                mLoginMenuItem.setText("Login");
                mLoginMenuItem.setBackground(SystemColor.menu);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mLoginMenuItem;
    }

    /**
     * Return the LoginPage property value.
     *
     * @return JPanel
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JPanel getLoginPage() {
        if (mLoginPage == null) {
            try {
                mLoginPage = new JPanel();
                mLoginPage.setName("LoginPage");
                mLoginPage.setLayout(new GridBagLayout());
                mLoginPage.setBackground(SystemColor.control);

                GridBagConstraints constraintsLoginEditorPanel = new GridBagConstraints();
                constraintsLoginEditorPanel.gridx = 0;
                constraintsLoginEditorPanel.gridy = 0;
                constraintsLoginEditorPanel.gridwidth = 6;
                constraintsLoginEditorPanel.fill = GridBagConstraints.BOTH;
                constraintsLoginEditorPanel.weightx = 1.0;
                constraintsLoginEditorPanel.weighty = 1.0;
                constraintsLoginEditorPanel.insets = new Insets(2, 2, 2, 2);
                getLoginPage().add(getLoginEditorPanel(),
                        constraintsLoginEditorPanel);

                GridBagConstraints constraintsLoginButton = new GridBagConstraints();
                constraintsLoginButton.gridx = 0;
                constraintsLoginButton.gridy = 1;
                constraintsLoginButton.insets = new Insets(2, 2, 2, 2);
                getLoginPage().add(getLoginButton(), constraintsLoginButton);

                GridBagConstraints constraintsLogoutButton = new GridBagConstraints();
                constraintsLogoutButton.gridx = 1;
                constraintsLogoutButton.gridy = 1;
                constraintsLogoutButton.insets = new Insets(2, 2, 2, 2);
                getLoginPage().add(getLogoutButton(), constraintsLogoutButton);

                GridBagConstraints constraintsLoadProjectButton = new GridBagConstraints();
                constraintsLoadProjectButton.gridx = 2;
                constraintsLoadProjectButton.gridy = 1;
                constraintsLoadProjectButton.insets = new Insets(2, 2, 2, 2);
                getLoginPage().add(getLoadProjectButton(),
                        constraintsLoadProjectButton);

                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mLoginPage;
    }

    /**
     * Return the LogMenu property value.
     *
     * @return JPopupMenu
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JPopupMenu getLogMenu() {
        if (mLogMenu == null) {
            try {
                mLogMenu = new JPopupMenu();
                mLogMenu.setName("LogMenu");
                mLogMenu.add(getCutMenuItem());
                mLogMenu.add(getCopyMenuItem());
                mLogMenu.add(getPasteMenuItem());
                mLogMenu.add(getJSeparator7());
                mLogMenu.add(getClearLogMenuItem());
                mLogMenu.add(getJSeparator7());
                mLogMenu.add(getLogProfileMenuItem1());
                mLogMenu.add(getLogProfileMenuItem());
                mLogMenu.add(getBrowseProfileMenuItem());
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mLogMenu;
    }

    /**
     * Return the LogoutButton property value.
     *
     * @return JButton
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JButton getLogoutButton() {
        if (mLogoutButton == null) {
            try {
                mLogoutButton = new JButton();
                mLogoutButton.setName("LogoutButton");
                mLogoutButton.setText("Logout");
                mLogoutButton.setBackground(SystemColor.control);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mLogoutButton;
    }

    /**
     * Return the LogoutMenuItem property value.
     *
     * @return JMenuItem
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JMenuItem getLogoutMenuItem() {
        if (mLogoutMenuItem == null) {
            try {
                mLogoutMenuItem = new JMenuItem();
                mLogoutMenuItem.setName("LogoutMenuItem");
                mLogoutMenuItem.setText("Logout");
                mLogoutMenuItem.setBackground(SystemColor.menu);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mLogoutMenuItem;
    }

    /**
     * Return the LogPage property value.
     *
     * @return JPanel
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JPanel getLogPage() {
        if (mLogPage == null) {
            try {
                mLogPage = new JPanel();
                mLogPage.setName("LogPage");
                mLogPage.setLayout(new GridBagLayout());
                mLogPage.setBackground(SystemColor.control);

                GridBagConstraints constraintsLogScrollPane = new GridBagConstraints();
                constraintsLogScrollPane.gridx = 0;
                constraintsLogScrollPane.gridy = 0;
                constraintsLogScrollPane.gridwidth = 13;
                constraintsLogScrollPane.fill = GridBagConstraints.BOTH;
                constraintsLogScrollPane.weightx = 1.0;
                constraintsLogScrollPane.weighty = 1.0;
                constraintsLogScrollPane.insets = new Insets(2, 2, 2, 2);
                getLogPage().add(getLogScrollPane(), constraintsLogScrollPane);

                GridBagConstraints constraintsClearLogButton = new GridBagConstraints();
                constraintsClearLogButton.gridx = 12;
                constraintsClearLogButton.gridy = 1;
                constraintsClearLogButton.anchor = GridBagConstraints.EAST;
                constraintsClearLogButton.insets = new Insets(2, 2, 2, 2);
                getLogPage()
                        .add(getClearLogButton(), constraintsClearLogButton);

                GridBagConstraints constraintsLogLabel = new GridBagConstraints();
                constraintsLogLabel.gridx = 0;
                constraintsLogLabel.gridy = 1;
                constraintsLogLabel.anchor = GridBagConstraints.WEST;
                constraintsLogLabel.insets = new Insets(2, 2, 2, 2);
                getLogPage().add(new JLabel("Log Level:"), constraintsLogLabel);

                GridBagConstraints constraintsLogCheckbox = new GridBagConstraints();
                constraintsLogCheckbox.gridx = 1;
                constraintsLogCheckbox.gridy = 1;
                constraintsLogCheckbox.fill = GridBagConstraints.HORIZONTAL;
                constraintsLogCheckbox.anchor = GridBagConstraints.WEST;
                constraintsLogCheckbox.insets = new Insets(2, 2, 2, 2);
                getLogPage().add(getLogLevelChoice(), constraintsLogCheckbox);

                GridBagConstraints constraintsProfileCheckbox = new GridBagConstraints();
                constraintsProfileCheckbox.gridx = 0;
                constraintsProfileCheckbox.gridy = 2;
                constraintsProfileCheckbox.anchor = GridBagConstraints.WEST;
                constraintsProfileCheckbox.insets = new Insets(2, 2, 2, 2);
                getLogPage().add(getProfileCheckbox(),
                        constraintsProfileCheckbox);

                GridBagConstraints constraintsLogProfileCheckbox = new GridBagConstraints();
                constraintsLogProfileCheckbox.gridx = 1;
                constraintsLogProfileCheckbox.gridy = 2;
                constraintsLogProfileCheckbox.anchor = GridBagConstraints.WEST;
                constraintsLogProfileCheckbox.insets = new Insets(2, 2, 2, 2);
                getLogPage().add(getLogProfileCheckbox(),
                        constraintsLogProfileCheckbox);

                GridBagConstraints constraintsBrowseProfileButton = new GridBagConstraints();
                constraintsBrowseProfileButton.gridx = 12;
                constraintsBrowseProfileButton.gridy = 2;
                constraintsBrowseProfileButton.anchor = GridBagConstraints.EAST;
                constraintsBrowseProfileButton.insets = new Insets(2, 2, 2, 2);
                getLogPage().add(getBrowseProfileButton(),
                        constraintsBrowseProfileButton);

            } catch (Throwable exception) {
                handleException(exception);
            }
        }
        return mLogPage;
    }

    private JCheckBox getLogProfileCheckbox() {
        if (mLogProfileCheckbox == null) {
            try {
                mLogProfileCheckbox = new JCheckBox();
                mLogProfileCheckbox.setName("LogProfileCheckbox");
                mLogProfileCheckbox.setText("Log Profile");
                mLogProfileCheckbox.setBackground(SystemColor.control);
            } catch (Throwable exception) {
                handleException(exception);
            }
        }
        return mLogProfileCheckbox;
    }

    /**
     * Return the LogProfileMenuItem property value.
     *
     * @return JCheckBoxMenuItem
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JCheckBoxMenuItem getLogProfileMenuItem() {
        if (mLogProfileMenuItem == null) {
            try {
                mLogProfileMenuItem = new JCheckBoxMenuItem();
                mLogProfileMenuItem.setName("LogProfileMenuItem");
                mLogProfileMenuItem.setText("Log Profile");
                mLogProfileMenuItem.setBackground(SystemColor.menu);
                mLogProfileMenuItem.setActionCommand("LogSQLMenuItem");
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mLogProfileMenuItem;
    }

    /**
     * Return the LogProfileMenuItem1 property value.
     *
     * @return JCheckBoxMenuItem
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JCheckBoxMenuItem getLogProfileMenuItem1() {
        if (mLogProfileMenuItem1 == null) {
            try {
                mLogProfileMenuItem1 = new JCheckBoxMenuItem();
                mLogProfileMenuItem1.setName("LogProfileMenuItem1");
                mLogProfileMenuItem1.setText("Profile");
                mLogProfileMenuItem1.setBackground(SystemColor.menu);
                mLogProfileMenuItem1.setActionCommand("ProfileMenuItem");
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mLogProfileMenuItem1;
    }

    /**
     * Return the LogScrollPane property value.
     *
     * @return JScrollPane
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JScrollPane getLogScrollPane() {
        if (mLogScrollPane == null) {
            try {
                mLogScrollPane = new JScrollPane();
                mLogScrollPane.setName("LogScrollPane");
                mLogScrollPane.setAutoscrolls(true);
                getLogScrollPane().setViewportView(getLogText());
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mLogScrollPane;
    }

    /**
     * Return the LogSplitter property value.
     *
     * @return JSplitPane
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JSplitPane getLogSplitter() {
        if (mLogSplitter == null) {
            try {
                mLogSplitter = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
                mLogSplitter.setName("LogSplitter");
                mLogSplitter.setAutoscrolls(true);
                mLogSplitter.setDividerSize(8);
                mLogSplitter.setMaximumSize(new Dimension(0, 0));
                mLogSplitter.setDividerLocation(300);
                mLogSplitter.setOneTouchExpandable(true);
                mLogSplitter.setMinimumSize(new Dimension(0, 0));
                getLogSplitter().add(getLogBook(), "bottom");
                getLogSplitter().add(getTopPanel(), "top");
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mLogSplitter;
    }

    /**
     * Return the LogText property value.
     *
     * @return JTextArea
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JTextArea getLogText() {
        if (mLogText == null) {
            try {
                mLogText = new JTextArea();
                mLogText.setName("LogText");
                mLogText.setAutoscrolls(true);
                mLogText.setBounds(0, 0, 10, 10);
                mLogText.setEditable(true);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mLogText;
    }

    /**
     * Return the PasteSQLMenuItem property value.
     *
     * @return JMenuItem
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JMenuItem getPasteSQLMenuItem() {
        if (mPasteSQLMenuItem == null) {
            try {
                mPasteSQLMenuItem = new JMenuItem();
                mPasteSQLMenuItem.setName("PasteSQLMenuItem");
                mPasteSQLMenuItem.setText("Paste");
                mPasteSQLMenuItem.setBackground(SystemColor.menu);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mPasteSQLMenuItem;
    }

    private JCheckBox getProfileCheckbox() {
        if (mProfileCheckbox == null) {
            try {
                mProfileCheckbox = new JCheckBox();
                mProfileCheckbox.setName("ProfileCheckbox");
                mProfileCheckbox.setText("Profile");
                mProfileCheckbox.setBackground(SystemColor.control);
            } catch (Throwable exception) {
                handleException(exception);
            }
        }
        return mProfileCheckbox;
    }

    private JButton getQueryButton() {
        if (mQueryButton == null) {
            try {
                mQueryButton = new JButton();
                mQueryButton.setName("QueryButton");
                mQueryButton.setText("Execute Query");
                mQueryButton.setBackground(SystemColor.control);
            } catch (Throwable exception) {
                handleException(exception);
            }
        }
        return mQueryButton;
    }

    /**
     * Return the QueryMenu property value.
     *
     * @return JPopupMenu
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JPopupMenu getQueryMenu() {
        if (mQueryMenu == null) {
            try {
                mQueryMenu = new JPopupMenu();
                mQueryMenu.setName("QueryMenu");
                mQueryMenu.add(getExecuteQueryMenuItem());
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mQueryMenu;
    }

    /**
     * Return the QueryPanel property value.
     *
     * @return JPanel
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JPanel getQueryPage() {
        if (mQueryPage == null) {
            try {
                mQueryPage = new JPanel();
                mQueryPage.setName("QueryPage");
                mQueryPage.setLayout(new GridBagLayout());
                mQueryPage.setBackground(SystemColor.control);

                GridBagConstraints constraintsQueryButton = new GridBagConstraints();
                constraintsQueryButton.gridx = 0;
                constraintsQueryButton.gridy = 1;
                constraintsQueryButton.anchor = GridBagConstraints.WEST;
                constraintsQueryButton.insets = new Insets(2, 2, 2, 2);
                getQueryPage().add(getQueryButton(), constraintsQueryButton);

                GridBagConstraints constraintsExpressionPanel = new GridBagConstraints();
                constraintsExpressionPanel.gridx = 0;
                constraintsExpressionPanel.gridy = 0;
                constraintsExpressionPanel.fill = GridBagConstraints.BOTH;
                constraintsExpressionPanel.weightx = 1.0;
                constraintsExpressionPanel.weighty = 1.0;
                getQueryPage().add(getExpressionPanel(),
                        constraintsExpressionPanel);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mQueryPage;
    }

    /**
     * Return the ResetDescriptorsMenuItem property value.
     *
     * @return JMenuItem
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JMenuItem getResetDescriptorsMenuItem() {
        if (mResetDescriptorsMenuItem == null) {
            try {
                mResetDescriptorsMenuItem = new JMenuItem();
                mResetDescriptorsMenuItem.setName("ResetDescriptorsMenuItem");
                mResetDescriptorsMenuItem.setText("Reset Descriptors");
                mResetDescriptorsMenuItem.setBackground(SystemColor.menu);
                mResetDescriptorsMenuItem.setForeground(Color.black);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mResetDescriptorsMenuItem;
    }

    /**
     * Return the ResultPage property value.
     *
     * @return JPanel
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JPanel getResultPage() {
        if (mResultPage == null) {
            try {
                mResultPage = new JPanel();
                mResultPage.setName("Query Results");
                mResultPage.setLayout(new GridBagLayout());
                mResultPage.setBackground(SystemColor.control);

                GridBagConstraints constraintsResultsScrollPane = new GridBagConstraints();
                constraintsResultsScrollPane.gridx = 0;
                constraintsResultsScrollPane.gridy = 0;
                constraintsResultsScrollPane.fill = GridBagConstraints.BOTH;
                constraintsResultsScrollPane.weightx = 1.0;
                constraintsResultsScrollPane.weighty = 1.0;
                constraintsResultsScrollPane.insets = new Insets(2, 2, 2, 2);
                getResultPage().add(getResultsScrollPane(),
                        constraintsResultsScrollPane);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mResultPage;
    }

    public Vector getResults() {
        return results;
    }

    /**
     * Return the ResultsScrollPane property value.
     *
     * @return JScrollPane
     */
    private JScrollPane getResultsScrollPane() {
        if (mResultsScrollPane == null) {
            try {
                mResultsScrollPane = new JScrollPane();
                mResultsScrollPane.setName("ResultsScrollPane");
                mResultsScrollPane
                        .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
                mResultsScrollPane
                        .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
                // mResultsScrollPane.setMaximumSize(new Dimension(0, 0));
                // mResultsScrollPane.setPreferredSize(new Dimension(0, 0));
                // mResultsScrollPane.setMinimumSize(new Dimension(0, 0));
                getResultsScrollPane().setViewportView(getResultsTable());
            } catch (Throwable exception) {
                handleException(exception);
            }
        }
        return mResultsScrollPane;
    }

    /**
     * Return the ResultsTable property value.
     *
     * @return JTable
     */
    private JTable getResultsTable() {
        if (mResultsTable == null) {
            try {
                mResultsTable = new JTable();
                mResultsTable.setName("ResultsTable");
                getResultsScrollPane().setColumnHeaderView(
                        mResultsTable.getTableHeader());
                mResultsTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
                // mResultsTable.setPreferredSize(new Dimension(700, 400));
                // mResultsTable.setBounds(0, 0, 200, 200);
                // mResultsTable.setPreferredScrollableViewportSize(new
                // Dimension(700, 400));
            } catch (Throwable exception) {
                handleException(exception);
            }
        }
        return mResultsTable;
    }

    /**
     * Return the SelectButton property value.
     *
     * @return JButton
     */
    private JButton getSelectButton() {
        if (mSelectButton == null) {
            try {
                mSelectButton = new JButton();
                mSelectButton.setName("SelectButton");
                mSelectButton.setText("Select");
                mSelectButton.setBackground(SystemColor.control);
            } catch (Throwable exception) {
                handleException(exception);
            }
        }
        return mSelectButton;
    }

    /**
     * Return the SelectSQLMenuItem property value.
     *
     * @return JMenuItem
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JMenuItem getSelectSQLMenuItem() {
        if (mSelectSQLMenuItem == null) {
            try {
                mSelectSQLMenuItem = new JMenuItem();
                mSelectSQLMenuItem.setName("SelectSQLMenuItem");
                mSelectSQLMenuItem.setText("Select SQL");
                mSelectSQLMenuItem.setBackground(SystemColor.menu);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mSelectSQLMenuItem;
    }

    /**
     * Gets the session property (org.eclipse.persistence.sessions.Session)
     * value.
     *
     * @return The session property value.
     * @see #setSession
     */
    public Session getSession() {
        return fieldSession;
    }

    /**
     * Return the SQLExecuteButton property value.
     *
     * @return JButton
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JButton getSQLExecuteButton() {
        if (mSQLExecuteButton == null) {
            try {
                mSQLExecuteButton = new JButton();
                mSQLExecuteButton.setName("SQLExecuteButton");
                mSQLExecuteButton.setText("Update");
                mSQLExecuteButton.setBackground(SystemColor.control);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mSQLExecuteButton;
    }

    private JButton getJPQLExecuteButton() {
        if (jpqlExecuteButton == null) {
            try {
                jpqlExecuteButton = new JButton();
                jpqlExecuteButton.setName("JPQLExecuteButton");
                jpqlExecuteButton.setText("Execute");
                jpqlExecuteButton.setBackground(SystemColor.control);
            } catch (Throwable exception) {
                handleException(exception);
            }
        }
        return jpqlExecuteButton;
    }

    private JButton getJavaExecuteButton() {
        if (javaExecuteButton == null) {
            try {
                javaExecuteButton = new JButton();
                javaExecuteButton.setName("JavaExecuteButton");
                javaExecuteButton.setText("Execute");
                javaExecuteButton.setBackground(SystemColor.control);
            } catch (Throwable exception) {
                handleException(exception);
            }
        }
        return javaExecuteButton;
    }

    /**
     * Return the SQLMenu property value.
     *
     * @return JPopupMenu
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JPopupMenu getSQLMenu() {
        if (mSQLMenu == null) {
            try {
                mSQLMenu = new JPopupMenu();
                mSQLMenu.setName("SQLMenu");
                mSQLMenu.add(getSQLUpdateMenuItem());
                mSQLMenu.add(getSQLSelectMenuItem());
                mSQLMenu.add(getJSeparator4());
                mSQLMenu.add(getClearSQLMenuItem());
                mSQLMenu.add(getJSeparator6());
                mSQLMenu.add(getCutSQLMenuItem());
                mSQLMenu.add(getCopySQLMenuItem());
                mSQLMenu.add(getPasteSQLMenuItem());
                mSQLMenu.add(getJSeparator5());
                mSQLMenu.add(getSQLTemplateMenu());
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mSQLMenu;
    }

    /**
     * Return the SQLScrollPane property value.
     *
     * @return JScrollPane
     */
    private JScrollPane getSQLScrollPane() {
        if (mSQLScrollPane == null) {
            try {
                mSQLScrollPane = new JScrollPane();
                mSQLScrollPane.setName("SQLScrollPane");
                getSQLScrollPane().setViewportView(getSQLText());
            } catch (Throwable exception) {
                handleException(exception);
            }
        }
        return mSQLScrollPane;
    }

    private JScrollPane getJPQLScrollPane() {
        JScrollPane pane = new JScrollPane();
        pane.setName("JPQLScrollPane");
        pane.setViewportView(getJPQLText());
        return pane;
    }

    private JScrollPane getJavaScrollPane() {
        if (javaScrollPane == null) {
            try {
                javaScrollPane = new JScrollPane();
                javaScrollPane.setName("JavaScrollPane");
                getJavaScrollPane().setViewportView(getJavaText());
            } catch (Throwable exception) {
                handleException(exception);
            }
        }
        return javaScrollPane;
    }

    /**
     * Return the SQLSelectMenuItem property value.
     *
     * @return JMenuItem
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JMenuItem getSQLSelectMenuItem() {
        if (mSQLSelectMenuItem == null) {
            try {
                mSQLSelectMenuItem = new JMenuItem();
                mSQLSelectMenuItem.setName("SQLSelectMenuItem");
                mSQLSelectMenuItem.setText("Execute SQL Select");
                mSQLSelectMenuItem.setBackground(SystemColor.menu);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mSQLSelectMenuItem;
    }

    /**
     * Return the SQLTemplateMenu property value.
     *
     * @return JMenu
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JMenu getSQLTemplateMenu() {
        if (mSQLTemplateMenu == null) {
            try {
                mSQLTemplateMenu = new JMenu();
                mSQLTemplateMenu.setName("SQLTemplateMenu");
                mSQLTemplateMenu.setText("SQL");
                mSQLTemplateMenu.setBackground(SystemColor.menu);
                mSQLTemplateMenu.add(getInsertSQLMenuItem());
                mSQLTemplateMenu.add(getUpdateSQLMenuItem());
                mSQLTemplateMenu.add(getDeleteSQLMenuItem());
                mSQLTemplateMenu.add(getSelectSQLMenuItem());
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mSQLTemplateMenu;
    }

    /**
     * Return the SQLText property value.
     *
     * @return JTextPane
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JTextPane getSQLText() {
        if (mSQLText == null) {
            try {
                mSQLText = new JTextPane();
                mSQLText.setName("SQLText");
                mSQLText
                        .setBorder(new javax.swing.plaf.basic.BasicBorders.MarginBorder());
                mSQLText.setBounds(0, 0, 467, 156);
                mSQLText.setMaximumSize(new Dimension(0, 0));
                mSQLText.setMinimumSize(new Dimension(1, 1));
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mSQLText;
    }

    private JTextPane getJPQLText() {
        if (jpqlText == null) {
            jpqlText = new JTextPane();
            jpqlText.setName("JPQLText");
            jpqlText.setBorder(new javax.swing.plaf.basic.BasicBorders.MarginBorder());
            jpqlText.setBounds(0, 0, 467, 156);
            jpqlText.setMaximumSize(new Dimension(0, 0));
            jpqlText.setMinimumSize(new Dimension(1, 1));
        }
        return jpqlText;
    }

    private JTextPane getJavaText() {
        if (javaText == null) {
            try {
                javaText = new JTextPane();
                javaText.setName("JavaText");
                javaText
                        .setBorder(new javax.swing.plaf.basic.BasicBorders.MarginBorder());
                javaText.setBounds(0, 0, 467, 156);
                javaText.setMaximumSize(new Dimension(0, 0));
                javaText.setMinimumSize(new Dimension(1, 1));
            } catch (Throwable exception) {
                handleException(exception);
            }
        }
        return javaText;
    }

    /**
     * Return the SQLUpdateMenuItem property value.
     *
     * @return JMenuItem
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JMenuItem getSQLUpdateMenuItem() {
        if (mSQLUpdateMenuItem == null) {
            try {
                mSQLUpdateMenuItem = new JMenuItem();
                mSQLUpdateMenuItem.setName("SQLUpdateMenuItem");
                mSQLUpdateMenuItem.setText("Execute SQL Update");
                mSQLUpdateMenuItem.setBackground(SystemColor.menu);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mSQLUpdateMenuItem;
    }

    /**
     * Return the TopPanel property value.
     *
     * @return JPanel
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    JPanel getTopPanel() {
        if (mTopPanel == null) {
            try {
                mTopPanel = new JPanel();
                mTopPanel.setName("TopPanel");
                mTopPanel.setLayout(new GridBagLayout());
                mTopPanel.setBackground(SystemColor.control);

                GridBagConstraints constraintsTopSplitPane = new GridBagConstraints();
                constraintsTopSplitPane.gridx = 0;
                constraintsTopSplitPane.gridy = 0;
                constraintsTopSplitPane.fill = GridBagConstraints.BOTH;
                constraintsTopSplitPane.weightx = 1.0;
                constraintsTopSplitPane.weighty = 1.0;
                constraintsTopSplitPane.ipady = 300;
                getTopPanel().add(getTopSplitPane(), constraintsTopSplitPane);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mTopPanel;
    }

    /**
     * Return the TopSplitPane property value.
     *
     * @return JSplitPane
     */
    private JSplitPane getTopSplitPane() {
        if (mTopSplitPane == null) {
            try {
                mTopSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
                mTopSplitPane.setName("TopSplitPane");
                mTopSplitPane.setDividerSize(8);
                mTopSplitPane.setOneTouchExpandable(true);
                mTopSplitPane.setDividerLocation(150);
                getTopSplitPane().add(getClassScrollPane(), "left");
                getTopSplitPane().add(getWorkspaceBook(), "right");
            } catch (Throwable exception) {
                handleException(exception);
            }
        }
        return mTopSplitPane;
    }

    /**
     * Return the UpdateSQLMenuItem property value.
     *
     * @return JMenuItem
     */
    private JMenuItem getUpdateSQLMenuItem() {
        if (mUpdateSQLMenuItem == null) {
            try {
                mUpdateSQLMenuItem = new JMenuItem();
                mUpdateSQLMenuItem.setName("UpdateSQLMenuItem");
                mUpdateSQLMenuItem.setText("Update SQL");
                mUpdateSQLMenuItem.setBackground(SystemColor.menu);
                // user code begin {1}
                // user code end
            } catch (Throwable exception) {
                // user code begin {2}
                // user code end
                handleException(exception);
            }
        }
        return mUpdateSQLMenuItem;
    }

    /**
     * Return the WorkspaceBook property value.
     *
     * @return JTabbedPane
     */
    public JTabbedPane getWorkspaceBook() {
        if (mWorkspaceBook == null) {
            try {
                mWorkspaceBook = new JTabbedPane();
                mWorkspaceBook.setName("WorkspaceBook");
                mWorkspaceBook.setAutoscrolls(false);
                mWorkspaceBook.setBackground(SystemColor.control);
                mWorkspaceBook.setMaximumSize(new Dimension(0, 0));
                mWorkspaceBook.setMinimumSize(new Dimension(1, 1));
                mWorkspaceBook
                        .insertTab("Login", null, getLoginPage(), null, 0);
                mWorkspaceBook
                        .insertTab("Cache", null, getCachePage(), null, 1);
                mWorkspaceBook
                        .insertTab("Query", null, getQueryPage(), null, 2);
                mWorkspaceBook.insertTab("JPQL", null, getJPQLPage(), null, 3);
                mWorkspaceBook.insertTab("SQL", null, getSQLPage(), null, 4);
                mWorkspaceBook.insertTab("Java", null, getJavaPage(), null, 5);
            } catch (Throwable exception) {
                handleException(exception);
            }
        }
        return mWorkspaceBook;
    }

    /**
     * Called whenever the part throws an exception.
     */
    private void handleException(Throwable exception) {
        /* Uncomment the following lines to print uncaught exceptions to stdout */
        System.out.println("--------- UNCAUGHT EXCEPTION ---------");
        exception.printStackTrace(System.out);
        MessageDialog.displayException(exception, this);
    }

    /**
     * Initializes connections
     */
    private void initConnections() throws Exception {
        getClassList().addListSelectionListener(this);
        getLoginButton().addActionListener(this);
        getLogoutButton().addActionListener(this);
        getLoadProjectButton().addActionListener(this);
        getClearLogButton().addActionListener(this);
        getBrowseProfileButton().addActionListener(this);
        getLogProfileCheckbox().addItemListener(this);
        getProfileCheckbox().addItemListener(this);
        getLogLevelChoice().addItemListener(this);
        getSelectButton().addActionListener(this);
        getSQLExecuteButton().addActionListener(this);
        getJPQLExecuteButton().addActionListener(this);
        getJavaExecuteButton().addActionListener(this);
        getClearButton().addActionListener(this);
        getJavaClearButton().addActionListener(this);
        getClearCacheButton().addActionListener(this);
        getInspectCacheButton().addActionListener(this);
        getQueryButton().addActionListener(this);
        getClearCacheMenuItem().addActionListener(this);
        getInspectCacheMenuItem().addActionListener(this);
        getSQLText().addMouseListener(this);
        getCacheTable().addMouseListener(this);
        getClassList().addMouseListener(this);
        getResultsTable().addMouseListener(this);
        getClearResultsMenuItem().addActionListener(this);
        getInspectResultMenuItem().addActionListener(this);
        getInspectDescriptorMenuItem().addActionListener(this);
        getClearDescriptorsMenuItem().addActionListener(this);
        getResetDescriptorsMenuItem().addActionListener(this);
        getInsertSQLMenuItem().addActionListener(this);
        getUpdateSQLMenuItem().addActionListener(this);
        getDeleteSQLMenuItem().addActionListener(this);
        getSelectSQLMenuItem().addActionListener(this);
        getSQLUpdateMenuItem().addActionListener(this);
        getSQLSelectMenuItem().addActionListener(this);
        getClearSQLMenuItem().addActionListener(this);
        getCutSQLMenuItem().addActionListener(this);
        getCopySQLMenuItem().addActionListener(this);
        getPasteSQLMenuItem().addActionListener(this);
        getLoginMenuItem().addActionListener(this);
        getLogoutMenuItem().addActionListener(this);
        getInspectSessionMenuItem1().addActionListener(this);
        getQueryPage().addMouseListener(this);
        getLogText().addMouseListener(this);
        getLoginPage().addMouseListener(this);
        getExecuteQueryMenuItem().addActionListener(this);
        getClearLogMenuItem().addActionListener(this);
        getBrowseProfileMenuItem().addActionListener(this);
        getBrowseProfileMenuItem().addPropertyChangeListener(this);
        getFullNamesMenuItem().addActionListener(this);
        connPtoP1SetTarget();
        connPtoP2SetTarget();
        connPtoP3SetTarget();
        connPtoP4SetTarget();
    }

    /**
     * Initialize the class.
     */
    private/* WARNING: THIS METHOD WILL BE REGENERATED. */
    void initialize() {
        try {
            // user code begin {1}
            setSession(new Project(new DatabaseLogin()).createDatabaseSession());
            // user code end
            setName("SessionInspectorPanel");
            setLayout(new GridBagLayout());
            setBackground(SystemColor.control);
            setSize(849, 588);

            GridBagConstraints constraintsLogSplitter = new GridBagConstraints();
            constraintsLogSplitter.gridx = 0;
            constraintsLogSplitter.gridy = 0;
            constraintsLogSplitter.fill = GridBagConstraints.BOTH;
            constraintsLogSplitter.weightx = 1.0;
            constraintsLogSplitter.weighty = 1.0;
            add(getLogSplitter(), constraintsLogSplitter);
            initConnections();
        } catch (Throwable exception) {
            handleException(exception);
        }

        setup();
    }

    public void inspect(Object object) {
        getLogText().append(String.valueOf(object));
        getLogText().append(Helper.cr());
        getLogBook().setSelectedComponent(getLogPage());
    }

    public void inspectDescriptor() {
        ClassInfo classInfo = ((ClassInfo) getClassList().getSelectedValue());
        if (classInfo == null) {
            return;
        }

        inspect(classInfo.descriptor);
    }

    public void inspectFromCache() {
        int index = getCacheTable().getSelectedRow();
        if (index < 0) {
            return;
        }
        Object result = getCacheResults().elementAt(index);
        if (result == null) {
            return;
        }

        inspect(result);
    }

    public void inspectResult() {
        int index = getResultsTable().getSelectedRow();
        if (index < 0) {
            return;
        }
        Object result = getResults().elementAt(index);
        if (result == null) {
            return;
        }

        inspect(result);
    }

    public void inspectSession() {
        inspect(getSession());
    }

    /**
     * Method to handle events for the ItemListener interface.
     *
     * @param e
     *                event.ItemEvent
     */
    @Override
    public void itemStateChanged(ItemEvent e) {
        if (e.getSource() == getLogProfileCheckbox()) {
            connEtoC14(e);
        }
        if (e.getSource() == getProfileCheckbox()) {
            connEtoC15(e);
        }
        if (e.getSource() == getLogLevelChoice()) {
            connEtoC16(e);
        }
    }

    public void loadLoginFromFile() {
        DatabaseLogin login = null;
        try {
            FileInputStream file = new FileInputStream("console.login");
            ObjectInputStream stream = new ObjectInputStream(file);
            DatabaseLogin fileLogin = (DatabaseLogin) stream.readObject();
            // Only copy over the connection properties.
            login = new DatabaseLogin();
            login.setDriverURLHeader(fileLogin.getDriverURLHeader());
            login.setDatabaseURL(fileLogin.getDatabaseURL());
            login.setDriverClassName(fileLogin.getDriverClassName());
            login.setPlatformClassName(fileLogin.getPlatformClassName());
            login.setUserName(fileLogin.getUserName());
            login.setEncryptedPassword(fileLogin.getPassword());
            stream.close();
            file.close();
        } catch (Throwable exception) {
            // Ignore file access errors if file access is not allowed then the
            // login will not be stored.
        }

        if (login == null) {
            return;
        }
        try {
            getLoginEditorPanel().setLogin(login);
        } catch (Exception exception) {
            // Incase the file is bad.
            getLoginEditorPanel().setLogin(new DatabaseLogin());
        }
    }

    public void loadProject() {
        JFileChooser dialog = new JFileChooser();
        dialog
                .setDialogTitle("Select Mapping Workbench project deployment XML file");
        javax.swing.filechooser.FileFilter filer = new javax.swing.filechooser.FileFilter() {
            @Override
            public boolean accept(File file) {
                return (file.getName().indexOf(".xml") != -1)
                        || file.isDirectory();
            }

            @Override
            public String getDescription() {
                return "XML Files (*.xml)";
            }
        };
        dialog.setFileFilter(filer);
        dialog.setCurrentDirectory(new File("."));
        int status = dialog.showOpenDialog(this);
        if (status == JFileChooser.CANCEL_OPTION) {
            return;
        }
        if (dialog.getSelectedFile() == null) {
            MessageDialog
                    .displayMessage("Invalid project file selected.", this);
            return;
        }

        showBusyCursor();
        try {
            String path = dialog.getSelectedFile().getPath();
            Project project = XMLProjectReader.read(path);
            if (getSession().isConnected()) {
                ((DatabaseSession) getSession()).addDescriptors(project);
            } else {
                ((AbstractSession) getSession()).setProject(project);
                getLoginEditorPanel().setLogin(
                        (DatabaseLogin) project.getDatasourceLogin());
            }
            resetDescriptors();
        } finally {
            showNormalCursor();
        }
    }

    public void loadSQLFromFile() {
        String sql = "";

        try {
            FileInputStream file = new FileInputStream("console.sql");
            byte[] data = new byte[file.available()];
            file.read(data);
            sql = new String(data);
            file.close();
        } catch (Exception exception) {
            // Ignore file access errors if file access is not allowed then the
            // login will not be stored.
        }

        getSQLText().setText(sql);
    }

    public void loggingChanged() {
        int logLevel = getLogLevelChoice().getSelectedIndex();
        if (logLevel != getSession().getLogLevel()) {
            getSession().setLogLevel(logLevel);
            getSession().getSessionLog().setShouldDisplayData(true);
            if (logLevel > SessionLog.FINEST) {
                getSession().getSessionLog().setShouldPrintConnection(false);
                getSession().getSessionLog().setShouldPrintDate(false);
                getSession().getSessionLog().setShouldPrintSession(false);
                getSession().getSessionLog().setShouldPrintThread(false);
            } else {
                getSession().getSessionLog().setShouldPrintConnection(true);
                getSession().getSessionLog().setShouldPrintDate(true);
                getSession().getSessionLog().setShouldPrintSession(true);
                getSession().getSessionLog().setShouldPrintThread(true);
            }
            // Also update all sessions in session manager.
            Iterator iterator = SessionManager.getManager().getSessions().values().iterator();
            while (iterator.hasNext()) {
                ((Session)iterator.next()).setSessionLog(getSession().getSessionLog());
            }
        }
    }

    public void login() {
        showBusyCursor();
        try {
            storeLoginToFile();

            updateLogin();

            ((DatabaseSession) getSession()).setLogin(getLoginEditorPanel()
                    .getLogin());
            ((DatabaseSession) getSession()).login();

            resetButtons();
        } finally {
            showNormalCursor();
        }
    }

    public void logout() {
        showBusyCursor();
        try {
            ((DatabaseSession) getSession()).logout();
            resetButtons();
            storeSQLToFile();
        } finally {
            showNormalCursor();
        }
    }

    public void logProfileChanged() {
        if ((getSession()).isInProfile()) {
            ((PerformanceProfiler) (getSession()).getProfiler())
                    .setShouldLogProfile(getLogProfileCheckbox().isSelected());
        }
    }

    /**
     * Method to handle events for the MouseListener interface.
     *
     * @param e
     *                event.MouseEvent
     */
    @Override
    public void mouseClicked(MouseEvent e) {
    }

    /**
     * Method to handle events for the MouseListener interface.
     *
     * @param e
     *                event.MouseEvent
     */
    @Override
    public void mouseEntered(MouseEvent e) {
    }

    /**
     * Method to handle events for the MouseListener interface.
     *
     * @param e
     *                event.MouseEvent
     */
    @Override
    public void mouseExited(MouseEvent e) {
    }

    /**
     * Method to handle events for the MouseListener interface.
     *
     * @param e
     *                event.MouseEvent
     */
    @Override
    public void mousePressed(MouseEvent e) {
    }

    /**
     * Method to handle events for the MouseListener interface.
     *
     * @param e
     *                event.MouseEvent
     */
    @Override
    public void mouseReleased(MouseEvent e) {
        if (e.getSource() == getSQLText()) {
            connEtoC18(e);
        }
        if (e.getSource() == getCacheTable()) {
            connEtoC19(e);
        }
        if (e.getSource() == getClassList()) {
            connEtoC21(e);
        }
        if (e.getSource() == getResultsTable()) {
            connEtoC20(e);
        }
        if (e.getSource() == getQueryPage()) {
            connEtoC40(e);
        }
        if (e.getSource() == getLogText()) {
            connEtoC41(e);
        }
        if (e.getSource() == getLoginPage()) {
            connEtoC42(e);
        }
    }

    public void pasteSQL() {
        getSQLText().paste();
    }

    public void profileChanged() {
        if ((getSession()).isInProfile()) {
            getSession().clearProfile();
        }
        if (getProfileCheckbox().isSelected()) {
            getSession().setProfiler(new PerformanceProfiler(getLogProfileCheckbox().isSelected()));
            getBrowseProfileButton().setEnabled(true);
            getLogProfileCheckbox().setEnabled(true);
        } else {
            getBrowseProfileButton().setEnabled(false);
            getLogProfileCheckbox().setEnabled(false);
        }
    }

    /**
     * Method to handle events for the PropertyChangeListener interface.
     *
     * @param evt
     *                java.beans.PropertyChangeEvent
     */
    @Override
    public void propertyChange(java.beans.PropertyChangeEvent evt) {
        if ((evt.getSource() == getBrowseProfileMenuItem())
                && (evt.getPropertyName().equals("enabled"))) {
            connPtoP1SetTarget();
        }
    }

    public void resetButtons() {
        boolean isConnected = (getSession() == null)
                || (getSession().isConnected());
        getLoginButton().setEnabled(!isConnected);
        getLogoutButton().setEnabled(isConnected);
        getQueryButton().setEnabled(isConnected);
        getSQLExecuteButton().setEnabled(isConnected);
        getSelectButton().setEnabled(isConnected);
    }

    public void resetCache() {
        Vector cacheResults = new Vector();
        setCacheResults(cacheResults);
        ClassInfo info = (ClassInfo) getClassList().getSelectedValue();
        DefaultTableModel model = new DefaultTableModel();
        if (info == null) {
            getCacheTable().setModel(model);
            getCacheTable().repaint();
            return;
        }

        IdentityMap map = ((AbstractSession) getSession())
                .getIdentityMapAccessorInstance().getIdentityMap(
                        info.descriptor.getJavaClass());
        for (Enumeration cacheEnum = map.keys(); cacheEnum.hasMoreElements();) {
            CacheKey key = (CacheKey) cacheEnum.nextElement();
            if (info.descriptor.getJavaClass().isInstance(key.getObject())) {
                cacheResults.addElement(key);
            }
        }

        String[] columns = new String[4];
        columns[0] = "Key";
        columns[1] = "Hash";
        columns[2] = "Version";
        columns[3] = "Object";

        model.setColumnIdentifiers(columns);
        for (Enumeration cacheEnumeration = cacheResults.elements(); cacheEnumeration
                .hasMoreElements();) {
            CacheKey key = (CacheKey) cacheEnumeration.nextElement();
            String[] values = new String[4];
            values[0] = key.getKey().toString();
            values[1] = Integer.valueOf(key.getObject().hashCode()).toString();
            values[2] = String.valueOf(key.getWriteLockValue());
            values[3] = key.getObject().toString();
            model.addRow(values);
        }

        getCacheTable().setModel(model);
        getCacheTable().repaint();
    }

    public void resetDescriptors() {
        if (getSession() == null) {
            return;
        }

        boolean useFullNames = getFullNamesMenuItem().isSelected();
        ClassInfo[] classes = new ClassInfo[(getSession()).getDescriptors()
                .size()];
        int index = 0;
        for (Iterator iterator = (getSession()).getDescriptors().values()
                .iterator(); iterator.hasNext();) {
            classes[index] = new ClassInfo((ClassDescriptor) iterator.next(),
                    useFullNames);
            index = index + 1;
        }
        Arrays.sort(classes, new ClassInfoCompare());

        DefaultListModel list = new DefaultListModel();
        for (index = 0; index < classes.length; index++) {
            list.addElement(classes[index]);
        }
        getClassList().setModel(list);
        getClassList().repaint();
        resetCache();
    }

    public void selectSQL() {
        showBusyCursor();
        try {
            String sql = getSQLText().getSelectedText();
            if ((sql == null) || (sql.length() == 0)) {
                return;
            }
            Vector rows = getSession().executeSelectingCall(new SQLCall(sql));
            setResultRows(rows);

            getLogBook().setSelectedComponent(getResultPage());
        } finally {
            showNormalCursor();
        }
    }

    public void setCacheResults(Vector cacheResults) {
        this.cacheResults = cacheResults;
    }

    public void setLog() {
        boolean autoscroll = false;

        // Check if from testing, then set manual autoscroll.
        if (getParent() instanceof JSplitPane) {
            autoscroll = true;
        }
        Writer log = new OutputStreamWriter(new TextAreaOutputStream(
                getLogText(), autoscroll));
        if (getSession() == null) {
            return;
        }

        getSession().setLog(log);
    }

    public void setResultObjects(Vector resultObjects,
            ClassDescriptor descriptor) {
        setResults(resultObjects);
        DefaultTableModel model = new DefaultTableModel();
        if (resultObjects.isEmpty()) {
            getResultsTable().setModel(model);
            getResultsTable().repaint();
            return;
        }

        String[] columns = new String[descriptor.getMappings().size()];
        for (int index = 0; index < descriptor.getMappings().size(); index++) {
            columns[index] = (descriptor.getMappings().elementAt(index))
                    .getAttributeName();
        }

        model.setColumnIdentifiers(columns);
        for (Enumeration objectsEnumeration = resultObjects.elements(); objectsEnumeration
                .hasMoreElements();) {
            Object object = objectsEnumeration.nextElement();
            String[] values = new String[descriptor.getMappings().size()];
            for (int index = 0; index < descriptor.getMappings().size(); index++) {
                DatabaseMapping mapping = descriptor.getMappings().elementAt(
                        index);
                values[index] = String.valueOf(mapping
                        .getAttributeValueFromObject(object));
            }
            model.addRow(values);
        }

        getResultsTable().setModel(model);
        getResultsTable().repaint();
    }

    public void setResultRows(Vector resultRows) {
        setResults(resultRows);
        DefaultTableModel model = new DefaultTableModel();
        if (resultRows.isEmpty()) {
            getResultsTable().setModel(model);
            getResultsTable().repaint();
            return;
        }
        DatabaseRecord firstRow = (DatabaseRecord) resultRows.firstElement();
        String[] columns = new String[firstRow.getFields().size()];
        for (int index = 0; index < firstRow.getFields().size(); index++) {
            columns[index] = firstRow.getFields().elementAt(
                    index).getName();
        }
        model.setColumnIdentifiers(columns);
        for (Enumeration rowsEnumeration = resultRows.elements(); rowsEnumeration
                .hasMoreElements();) {
            DatabaseRecord row = (DatabaseRecord) rowsEnumeration.nextElement();
            String[] values = new String[row.getValues().size()];
            for (int index = 0; index < row.getValues().size(); index++) {
                values[index] = String
                        .valueOf(row.getValues().elementAt(index));
            }
            model.addRow(values);
        }

        getResultsTable().setModel(model);
        getResultsTable().repaint();
    }

    public void setResultReports(Vector results) {
        setResults(results);
        DefaultTableModel model = new DefaultTableModel();
        if (results.isEmpty()) {
            getResultsTable().setModel(model);
            getResultsTable().repaint();
            return;
        }
        Object first = results.get(0);
        if (first instanceof ReportQueryResult) {
            ReportQueryResult result = (ReportQueryResult) results.get(0);
            String[] columns = new String[result.getNames().size()];
            for (int index = 0; index < result.getNames().size(); index++) {
                columns[index] = result.getNames().get(index);
            }
            model.setColumnIdentifiers(columns);
            for (Iterator iterator = results.iterator(); iterator.hasNext();) {
                result = (ReportQueryResult) iterator.next();
                String[] values = new String[result.getResults().size()];
                for (int index = 0; index < result.getResults().size(); index++) {
                    values[index] = String.valueOf(result.getByIndex(index));
                }
                model.addRow(values);
            }
        } else if (first instanceof Object[]) {
            Object[] result = (Object[]) results.get(0);
            String[] columns = new String[result.length];
            for (int index = 0; index < result.length; index++) {
                columns[index] = String.valueOf(index);
            }
            model.setColumnIdentifiers(columns);
            for (Iterator iterator = results.iterator(); iterator.hasNext();) {
                result = (Object[]) iterator.next();
                String[] values = new String[result.length];
                for (int index = 0; index < result.length; index++) {
                    values[index] = String.valueOf(result[index]);
                }
                model.addRow(values);
            }
        } else {
            String[] columns = new String[1];
            columns[0] = "value";
            model.setColumnIdentifiers(columns);
            for (Iterator iterator = results.iterator(); iterator.hasNext();) {
                Object result = iterator.next();
                String[] values = new String[1];
                values[0] = String.valueOf(result);
                model.addRow(values);
            }
        }

        getResultsTable().setModel(model);
        getResultsTable().repaint();
    }

    public void setResults(Vector results) {
        this.results = results;
    }

    /**
     * Sets the session property (org.eclipse.persistence.sessions.Session)
     * value.
     *
     * @param session
     *                The new value for the property.
     * @see #getSession
     */
    public void setSession(Session session) {
        Session oldValue = fieldSession;
        fieldSession = session;
        firePropertyChange("session", oldValue, session);

        getSession().setLogLevel(getLogLevelChoice().getSelectedIndex());

        // Do not set if not a DatabaseLogin, i.e. EIS login.
        if (getSession().getDatasourceLogin() instanceof DatabaseLogin) {
            getLoginEditorPanel().setLogin(
                    (DatabaseLogin) (getSession()).getDatasourceLogin());
        }
        resetDescriptors();
        resetButtons();
        setLog();
    }

    public void setup() {
        resetButtons();
        logProfileChanged();
        profileChanged();
        getExpressionPanel().reset();
        getLoginEditorPanel().reset();
        loadLoginFromFile();
        loadSQLFromFile();
    }

    /**
     * Change to the busy cursor.
     */
    public void showBusyCursor() {
        Container parent = this;
        while (parent != null) {
            parent.setCursor(java.awt.Cursor
                    .getPredefinedCursor(java.awt.Cursor.WAIT_CURSOR));
            parent = parent.getParent();
        }
    }

    /**
     * Change from the busy cursor.
     */
    public void showNormalCursor() {
        Container parent = this;
        while (parent != null) {
            parent.setCursor(java.awt.Cursor
                    .getPredefinedCursor(java.awt.Cursor.DEFAULT_CURSOR));
            parent = parent.getParent();
        }
    }

    public void storeLoginToFile() {
        DatabaseLogin login = getLoginEditorPanel().getLogin();
        try {
            FileOutputStream file = new FileOutputStream("console.login");
            ObjectOutputStream stream = new ObjectOutputStream(file);
            stream.writeObject(login);
            stream.flush();
            file.flush();
            stream.close();
            file.close();
        } catch (Exception exception) {
            // Ignore file access errors if file access is not allowed then the
            // login will not be stored.
        }
    }

    public void storeSQLToFile() {
        String sql = getSQLText().getText();

        try {
            FileOutputStream file = new FileOutputStream("console.sql");
            file.write(sql.getBytes());
            file.flush();
            file.close();
        } catch (Exception exception) {
            // Ignore file access errors if file access is not allowed then the
            // login will not be stored.
        }
    }

    public void templateSQLDelete() {
        getSQLText().setText(
                getSQLText().getText() + "\n\nDelete from <table> where <exp>");
    }

    public void templateSQLInsert() {
        getSQLText()
                .setText(
                        getSQLText().getText()
                                + "\n\nInsert into <table> (<fields>) values (<values>)");
    }

    public void templateSQLSelect() {
        getSQLText()
                .setText(
                        getSQLText().getText()
                                + "\n\nSelect <fields> from <tables> where <exp> order by <exp> group by <exp>");
    }

    public void templateSQLUpdate() {
        getSQLText()
                .setText(
                        getSQLText().getText()
                                + "\n\nUpdate <table> set <<field> = <value>> where <exp>");
    }

    /**
     * Method to handle events for the ListSelectionListener interface.
     *
     * @param e
     *                event.ListSelectionEvent
     */
    @Override
    public void valueChanged(ListSelectionEvent e) {
        if (e.getSource() == getClassList()) {
            connEtoC3(e);
        }
    }

    private void updateLogin() {
        if (shouldUseJndiConnector
                && getLoginEditorPanel().getLogin().getPlatform().isOracle()) {
            try {
                Class connectionPoolHelperClass = Class
                        .forName("org.eclipse.persistence.tools.sessionconsole.OracleConnectionPoolHelper");
                Class[] params = new Class[] { java.lang.String.class };
                java.lang.reflect.Method method = connectionPoolHelperClass
                        .getDeclaredMethod("getOracleDataSource", params);
                Object[] args = new Object[] { getLoginEditorPanel().getLogin()
                        .getConnectionString() };
                javax.sql.DataSource datasource = (javax.sql.DataSource) method
                        .invoke(null, args);
                if (datasource == null) {
                    return;
                }
                org.eclipse.persistence.sessions.JNDIConnector jndiConnector = new org.eclipse.persistence.sessions.JNDIConnector();
                jndiConnector.setDataSource(datasource);
                getLoginEditorPanel().getLogin().setConnector(jndiConnector);
                getLoginEditorPanel().getLogin()
                        .setUsesExternalConnectionPooling(true);
            } catch (Exception e) {
                System.out
                        .println("Got exception while updating Session console login.  This usually results from running on a system not compiled with "
                                + " Oracle dependencies.  If you are not running on Oracle, this is not a problem.");
                handleException(e);
            }
        }
    }
}
