/*
 * Smart GWT (GWT for SmartClient)
 * Copyright 2008 and beyond, Isomorphic Software, Inc.
 *
 * Smart GWT is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License version 3
 * as published by the Free Software Foundation.  Smart GWT is also
 * available under typical commercial license terms - see
 * http://smartclient.com/license
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 */
/* sgwtgen */
 
package com.smartgwt.client.tools;


import com.smartgwt.client.event.*;
import com.smartgwt.client.core.*;
import com.smartgwt.client.types.*;
import com.smartgwt.client.data.*;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.data.events.*;
import com.smartgwt.client.browser.window.*;
import com.smartgwt.client.rpc.*;
import com.smartgwt.client.ai.*;
import com.smartgwt.client.callbacks.*;
import com.smartgwt.client.tools.*;
import com.smartgwt.client.bean.*;
import com.smartgwt.client.widgets.*;
import com.smartgwt.client.widgets.ai.*;
import com.smartgwt.client.widgets.events.*;
import com.smartgwt.client.widgets.form.*;
import com.smartgwt.client.widgets.form.validator.*;
import com.smartgwt.client.widgets.form.fields.*;
import com.smartgwt.client.widgets.tile.*;
import com.smartgwt.client.widgets.tile.events.*;
import com.smartgwt.client.widgets.grid.*;
import com.smartgwt.client.widgets.grid.events.*;
import com.smartgwt.client.widgets.chart.*;
import com.smartgwt.client.widgets.layout.*;
import com.smartgwt.client.widgets.layout.events.*;
import com.smartgwt.client.widgets.menu.*;
import com.smartgwt.client.widgets.tour.*;
import com.smartgwt.client.widgets.notify.*;
import com.smartgwt.client.widgets.rte.*;
import com.smartgwt.client.widgets.rte.events.*;
import com.smartgwt.client.widgets.ace.*;
import com.smartgwt.client.widgets.ace.events.*;
import com.smartgwt.client.widgets.tab.*;
import com.smartgwt.client.widgets.toolbar.*;
import com.smartgwt.client.widgets.tree.*;
import com.smartgwt.client.widgets.tree.events.*;
import com.smartgwt.client.widgets.tableview.*;
import com.smartgwt.client.widgets.viewer.*;
import com.smartgwt.client.widgets.calendar.*;
import com.smartgwt.client.widgets.calendar.events.*;
import com.smartgwt.client.widgets.cube.*;
import com.smartgwt.client.widgets.notify.*;
import com.smartgwt.client.widgets.drawing.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.gwt.event.shared.*;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.core.client.JavaScriptObject;

import com.smartgwt.client.util.*;
import com.smartgwt.client.util.events.*;
import com.smartgwt.client.util.workflow.*;
import com.smartgwt.client.util.workflow.Process; // required to override java.lang.Process
import com.smartgwt.client.util.tour.*;

import com.smartgwt.logicalstructure.core.*;
import com.smartgwt.logicalstructure.widgets.*;
import com.smartgwt.logicalstructure.widgets.drawing.*;
import com.smartgwt.logicalstructure.widgets.plugins.*;
import com.smartgwt.logicalstructure.widgets.form.*;
import com.smartgwt.logicalstructure.widgets.tile.*;
import com.smartgwt.logicalstructure.widgets.grid.*;
import com.smartgwt.logicalstructure.widgets.chart.*;
import com.smartgwt.logicalstructure.widgets.layout.*;
import com.smartgwt.logicalstructure.widgets.menu.*;
import com.smartgwt.logicalstructure.widgets.rte.*;
import com.smartgwt.logicalstructure.widgets.ace.*;
import com.smartgwt.logicalstructure.widgets.tab.*;
import com.smartgwt.logicalstructure.widgets.tableview.*;
import com.smartgwt.logicalstructure.widgets.toolbar.*;
import com.smartgwt.logicalstructure.widgets.tree.*;
import com.smartgwt.logicalstructure.widgets.viewer.*;
import com.smartgwt.logicalstructure.widgets.calendar.*;
import com.smartgwt.logicalstructure.widgets.cube.*;
import com.smartgwt.logicalstructure.widgets.tools.*;
import com.smartgwt.logicalstructure.widgets.tour.*;
import com.smartgwt.logicalstructure.widgets.ai.*;

/**
 * An application available within {@link com.smartgwt.client.docs.ReifyOnSite Reify OnSite} that allows developers to
 * create and manage Smart GWT screens and datasources.  Only <b>internal framework code</b> can create an instance of the
 * Reify tool -  do not try it directly in your applications.  If you want to create visual tools similar to Reify, see
 * {@link com.smartgwt.client.docs.DevTools the Dashboards & Tools framework overview}. <p> Note that in the Smart GWT SDK,
 * this class present only to provide {@link com.smartgwt.client.docs.ReifyForDevelopers Reify} utility class method APIs,
 * and is not an instantiable widget.  For example, you can call {@link com.smartgwt.client.tools.Reify#getMockDS
 * getMockDS()} to export a {@link com.smartgwt.client.data.DataSource} as XML-formatted values and metadata for importing
 * into Reify to create a {@link com.smartgwt.client.data.MockDataSource}.
 * @see com.smartgwt.client.docs.Reify Reify Overview
 */
@BeanFactory.FrameworkClass
@BeanFactory.ScClassName("Reify")
public class Reify extends VLayout {

    public static Reify getOrCreateRef(JavaScriptObject jsObj) {
        if (jsObj == null) return null;
        final BaseWidget refInstance = BaseWidget.getRef(jsObj);
        if (refInstance == null) {
            return new Reify(jsObj);
        } else {
            assert refInstance instanceof Reify;
            return (Reify)refInstance;
        }
    }
        


    /**
     * Changes the defaults for Canvas AutoChildren named <code>autoChildName</code>.
     *
     * @param autoChildName name of an AutoChild to customize the defaults for.
     * @param defaults Canvas defaults to apply. These defaults override any existing properties
     * without destroying or wiping out non-overridden properties.  For usage tips on this
     * param, see {@link com.smartgwt.client.docs.SGWTProperties}.
     * @see com.smartgwt.client.docs.AutoChildUsage
     */
    public static native void changeAutoChildDefaults(String autoChildName, Canvas defaults) /*-{
        if (defaults.@com.smartgwt.client.widgets.BaseWidget::isCreated()()) {
            @com.smartgwt.client.util.ConfigUtil::warnOfPreConfigInstantiation(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;)(Reify.@java.lang.Object::getClass()(), "changeAutoChildDefaults", "Canvas");
        }
        defaults.@com.smartgwt.client.widgets.BaseWidget::setConfigOnly(Z)(true);
        var cleanDefaultsJS = @com.smartgwt.client.util.JSOHelper::cleanProperties(Lcom/google/gwt/core/client/JavaScriptObject;Z)(defaults.@com.smartgwt.client.widgets.BaseWidget::getConfig()(), true);
        $wnd.isc.Reify.changeDefaults(autoChildName + "Defaults", cleanDefaultsJS);
    }-*/;

    /**
     * Changes the defaults for FormItem AutoChildren named <code>autoChildName</code>.
     *
     * @param autoChildName name of an AutoChild to customize the defaults for.
     * @param defaults FormItem defaults to apply. These defaults override any existing properties
     * without destroying or wiping out non-overridden properties.  For usage tips on this
     * param, see {@link com.smartgwt.client.docs.SGWTProperties}.
     * @see com.smartgwt.client.docs.AutoChildUsage
     */
    public static native void changeAutoChildDefaults(String autoChildName, FormItem defaults) /*-{
        if (defaults.@com.smartgwt.client.widgets.form.fields.FormItem::isCreated()()) {
            @com.smartgwt.client.util.ConfigUtil::warnOfPreConfigInstantiation(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;)(Reify.@java.lang.Object::getClass()(), "changeAutoChildDefaults", "FormItem");
        }
        defaults.@com.smartgwt.client.widgets.form.fields.FormItem::setConfigOnly(Z)(true);
    	var cleanDefaultsJS = defaults.@com.smartgwt.client.widgets.form.fields.FormItem::getEditorTypeConfig()();
        $wnd.isc.Reify.changeDefaults(autoChildName + "Defaults", cleanDefaultsJS);
    }-*/;

    public Reify(){
        setID("VB");
        scClassName = "Reify";
    }

    public Reify(JavaScriptObject jsObj){
        scClassName = "Reify";
        setJavaScriptObject(jsObj);
    }

    protected native JavaScriptObject create()/*-{
        var config = this.@com.smartgwt.client.widgets.BaseWidget::getConfig()();
        var scClassName = this.@com.smartgwt.client.widgets.BaseWidget::scClassName;
        var widget = $wnd.isc[scClassName].create(config);
        if ($wnd.isc.keepGlobals) this.@com.smartgwt.client.widgets.BaseWidget::internalSetID(Lcom/google/gwt/core/client/JavaScriptObject;)(widget);
        this.@com.smartgwt.client.widgets.BaseWidget::doInit()();
        return widget;
    }-*/;

    // ********************* Static Attributes ***********************

    // ********************* Properties / Attributes ***********************

    /**
     * The {@link com.smartgwt.client.data.DataSource} to use for saving the project, using fileSource operations. If not set,
     * the property defaults to "vbProjects" except in hostedMode where "isc_hostedProjects" is the default.
     *
     * @param projectDataSource New projectDataSource value. Default value is null
     * @return {@link com.smartgwt.client.tools.Reify Reify} instance, for chaining setter calls
     * @throws IllegalStateException this property cannot be changed after the component has been created
     * @see com.smartgwt.client.docs.Reify Reify Overview
     */
    public Reify setProjectDataSource(DataSource projectDataSource)  throws IllegalStateException {
        return (Reify)setAttribute("projectDataSource", projectDataSource == null ? null : projectDataSource.getOrCreateJsObj(), false);
    }

    /**
     * The {@link com.smartgwt.client.data.DataSource} to use for saving the project, using fileSource operations. If not set,
     * the property defaults to "vbProjects" except in hostedMode where "isc_hostedProjects" is the default.
     *
     * @return Current projectDataSource value. Default value is null
     * @see com.smartgwt.client.docs.Reify Reify Overview
     */
    public DataSource getProjectDataSource()  {
        return DataSource.getOrCreateRef(getAttributeAsJavaScriptObject("projectDataSource"));
    }

    /**
     * The {@link com.smartgwt.client.data.DataSource} to use for saving the project, using fileSource operations. If not set,
     * the property defaults to "vbProjects" except in hostedMode where "isc_hostedProjects" is the default.
     *
     * @param projectDataSource New projectDataSource value. Default value is null
     * @return {@link com.smartgwt.client.tools.Reify Reify} instance, for chaining setter calls
     * @throws IllegalStateException this property cannot be changed after the component has been created
     * @see com.smartgwt.client.docs.Reify Reify Overview
     */
    public Reify setProjectDataSource(String projectDataSource)  throws IllegalStateException {
        return (Reify)setAttribute("projectDataSource", projectDataSource, false);
    }

    /**
     * The {@link com.smartgwt.client.data.DataSource} to use for saving the project, using fileSource operations. If not set,
     * the property defaults to "vbProjects" except in hostedMode where "isc_hostedProjects" is the default.
     *
     * @return Current projectDataSource value. Default value is null
     * @see com.smartgwt.client.docs.Reify Reify Overview
     */
    public String getProjectDataSourceAsString()  {
        return getAttributeAsString("projectDataSource");
    }
    

    // ********************* Methods ***********************
	/**
     * Loads an existing project from {@link com.smartgwt.client.tools.Reify#getProjectDataSource projectDataSource} within
     * Reify making it the current project. If project cannot be found a new project will be created and loaded. <P> The last
     * accessed screen within the project is restored to the current screen.
     * @param projectName the name of the project to load
     */
    public native void loadProject(String projectName) /*-{
        if (this.@com.smartgwt.client.widgets.BaseWidget::isConfigOnly()()) {
            @com.smartgwt.client.util.ConfigUtil::warnOfPostConfigInstantiation(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;)(this.@java.lang.Object::getClass()(), "loadProject", "String");
        }
        var self = this.@com.smartgwt.client.widgets.BaseWidget::getOrCreateJsObj()();
        self.loadProject(projectName);
    }-*/;

    /**
     * See {@link Reify#loadProject(java.lang.String, java.lang.String, com.smartgwt.client.core.Function) loadProject()}
     */
    public void loadProject(String projectName, String ownerId){
        loadProject(projectName, ownerId, null);
    }

	/**
     * Loads an existing project from {@link com.smartgwt.client.tools.Reify#getProjectDataSource projectDataSource} within
     * Reify making it the current project. If project cannot be found a new project will be created and loaded. <P> The last
     * accessed screen within the project is restored to the current screen.
     * @param projectName the name of the project to load
     * @param ownerId optional ID of the project owner
     * @param callback optional callback to fire when the project has been loaded
     */
    public native void loadProject(String projectName, String ownerId, Function callback) /*-{
        if (this.@com.smartgwt.client.widgets.BaseWidget::isConfigOnly()()) {
            @com.smartgwt.client.util.ConfigUtil::warnOfPostConfigInstantiation(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;)(this.@java.lang.Object::getClass()(), "loadProject", "String,String,Function");
        }
        var self = this.@com.smartgwt.client.widgets.BaseWidget::getOrCreateJsObj()();
        self.loadProject(projectName, ownerId, 
			$entry( function() { 
				if(callback!=null) callback.@com.smartgwt.client.core.Function::execute()(
				);
			}));
    }-*/;
	

    // ********************* Static Methods ***********************

	/**
     * Add one or more screens to an existing Reify project.  The screens must already be saved via {@link
     * com.smartgwt.client.tools.Reify#saveScreen saveScreen()}. The project is loaded from vbProjects, the screen references
     * are appended, and the project is saved back.
     * @param projectName project name
     * @param screenNames screen names to add
     */
    public static native void addScreensToProject(String projectName, String[] screenNames) /*-{
        $wnd.isc.Reify.addScreensToProject(projectName, @com.smartgwt.client.util.JSOHelper::convertToJavaScriptArray([Ljava/lang/Object;)(screenNames));
    }-*/;

	/**
     * Add one or more screens to an existing Reify project.  The screens must already be saved via {@link
     * com.smartgwt.client.tools.Reify#saveScreen saveScreen()}. The project is loaded from vbProjects, the screen references
     * are appended, and the project is saved back.
     * @param projectName project name
     * @param screenNames screen names to add
     * @param callback called with     (DSResponse dsResponse, Object data)
     */
    public static native void addScreensToProject(String projectName, String[] screenNames, Function callback) /*-{
        $wnd.isc.Reify.addScreensToProject(projectName, @com.smartgwt.client.util.JSOHelper::convertToJavaScriptArray([Ljava/lang/Object;)(screenNames), 
			$entry( function() { 
				if(callback!=null) callback.@com.smartgwt.client.core.Function::execute()(
				);
			}));
    }-*/;
	

	/**
     * Create a minimal Reify project that references one or more screens already stored in {@link
     * com.smartgwt.client.tools.Reify#saveScreen vbScreens}. The project is saved to vbProjects. <P> If a project with this
     * name already exists, it is overwritten. To add screens to an existing project, use {@link
     * com.smartgwt.client.tools.Reify#addScreensToProject addScreensToProject()} instead.
     * @param projectName project name
     * @param screenNames screen names to include
     */
    public static native void createProjectWithScreens(String projectName, String[] screenNames) /*-{
        $wnd.isc.Reify.createProjectWithScreens(projectName, @com.smartgwt.client.util.JSOHelper::convertToJavaScriptArray([Ljava/lang/Object;)(screenNames));
    }-*/;

	/**
     * Create a minimal Reify project that references one or more screens already stored in {@link
     * com.smartgwt.client.tools.Reify#saveScreen vbScreens}. The project is saved to vbProjects. <P> If a project with this
     * name already exists, it is overwritten. To add screens to an existing project, use {@link
     * com.smartgwt.client.tools.Reify#addScreensToProject addScreensToProject()} instead.
     * @param projectName project name
     * @param screenNames screen names to include
     * @param callback called with     (DSResponse dsResponse, Object data)
     */
    public static native void createProjectWithScreens(String projectName, String[] screenNames, Function callback) /*-{
        $wnd.isc.Reify.createProjectWithScreens(projectName, @com.smartgwt.client.util.JSOHelper::convertToJavaScriptArray([Ljava/lang/Object;)(screenNames), 
			$entry( function() { 
				if(callback!=null) callback.@com.smartgwt.client.core.Function::execute()(
				);
			}));
    }-*/;
	

	/**
     * Hide the overlay view, destroying all overlay frames.  The loaded screen canvases are untouched.  Idempotent.
     */
    public static native void disableOverlay() /*-{
        $wnd.isc.Reify.disableOverlay();
    }-*/;


	/**
     * Save an {@link com.smartgwt.client.tools.EditContext}'s component tree (or raw screen XML) to Reify storage and open it
     * in the Reify editor.  This is the primary convenience method for the "Dashboards &amp; Tools to Reify" workflow. <P> The
     * method handles the complete flow: <ol> <li>Serializes the EditContext to screen XML (if     <code>editContext</code> is
     * provided instead of raw     <code>screenContents</code>)</li> <li>Saves the screen to vbScreens via     {@link
     * com.smartgwt.client.tools.Reify#saveScreen saveScreen()}</li> <li>Creates a new project or adds the screen to an    
     * existing project</li> <li>Opens Reify via {@link com.smartgwt.client.tools.Reify#loadReify loadReify()} with the    
     * project and screen pre-selected</li> </ol>
     * @param config configuration
     */
    public static native void editInReify(EditInReifyConfig config) /*-{
        $wnd.isc.Reify.editInReify(config.@com.smartgwt.client.core.DataClass::getJsObj()());
    }-*/;

	/**
     * Save an {@link com.smartgwt.client.tools.EditContext}'s component tree (or raw screen XML) to Reify storage and open it
     * in the Reify editor.  This is the primary convenience method for the "Dashboards &amp; Tools to Reify" workflow. <P> The
     * method handles the complete flow: <ol> <li>Serializes the EditContext to screen XML (if     <code>editContext</code> is
     * provided instead of raw     <code>screenContents</code>)</li> <li>Saves the screen to vbScreens via     {@link
     * com.smartgwt.client.tools.Reify#saveScreen saveScreen()}</li> <li>Creates a new project or adds the screen to an    
     * existing project</li> <li>Opens Reify via {@link com.smartgwt.client.tools.Reify#loadReify loadReify()} with the    
     * project and screen pre-selected</li> </ol>
     * @param config configuration
     * @param callback called with a     ReifyRemote instance
     */
    public static native void editInReify(EditInReifyConfig config, Function callback) /*-{
        $wnd.isc.Reify.editInReify(config.@com.smartgwt.client.core.DataClass::getJsObj()(), 
			$entry( function() { 
				if(callback!=null) callback.@com.smartgwt.client.core.Function::execute()(
				);
			}));
    }-*/;
	

	/**
     * Show the overlay view.  Equivalent to <code>showOverlay()</code> with default dismiss settings (Escape key dismisses,
     * click-outside dismisses). Idempotent.
     */
    public static native void enableOverlay() /*-{
        $wnd.isc.Reify.enableOverlay();
    }-*/;


	/**
     * Determine which cached Reify project a DataSource belongs to, if any.
     * @param dataSourceId DataSource ID
     *
     * @return the project containing the DS, or null
     */
    public static native Project getDataSourceProject(String dataSourceId) /*-{
        var ret = $wnd.isc.Reify.getDataSourceProject(dataSourceId);
        if(ret == null) return null;
        return @com.smartgwt.client.rpc.Project::getOrCreateRef(Lcom/google/gwt/core/client/JavaScriptObject;)(ret);
    }-*/;


	/**
     * Return a {@link com.smartgwt.client.data.DataSource} for browsing the list of DataSources in a Reify installation.  See
     * {@link com.smartgwt.client.tools.Reify#getProjectsDS getProjectsDS()} for behavior, settings, and remote-access details.
     * @param callback called with <code>(DataSource ds)</code>.
     * See {@link com.smartgwt.client.docs.Callback Callback}
     * @param settings optional override settings
     */
    public static native void getDataSourcesDS(String callback, ReifyDSSettings settings) /*-{
        $wnd.isc.Reify.getDataSourcesDS(callback, settings.@com.smartgwt.client.core.DataClass::getJsObj()());
    }-*/;


	/**
     * Return an Array of records describing every Reify-loaded {@link com.smartgwt.client.data.DataSource} currently
     * registered.
     *
     * @return loaded DataSource records
     */
    public static native Map[] getLoadedDataSources() /*-{
        var ret = $wnd.isc.Reify.getLoadedDataSources();
        if(ret == null) return null;
        return @com.smartgwt.client.util.ConvertTo::arrayOfMap(Lcom/google/gwt/core/client/JavaScriptObject;)(ret);
    }-*/;


	/**
     * Return a live clientOnly {@link com.smartgwt.client.data.DataSource} of loaded DataSource records.  See {@link
     * com.smartgwt.client.tools.Reify#getLoadedProjectsDS getLoadedProjectsDS()}.
     *
     * @return live discovery DS for DataSources
     */
    public static native DataSource getLoadedDataSourcesDS() /*-{
        var ret = $wnd.isc.Reify.getLoadedDataSourcesDS();
        if(ret == null) return null;
        return @com.smartgwt.client.data.DataSource::getOrCreateRef(Lcom/google/gwt/core/client/JavaScriptObject;)(ret);
    }-*/;


	/**
     * Return an Array of records describing every Reify {@link com.smartgwt.client.rpc.Project} currently registered in the
     * loaded-resource registry.  Each record has fields <code>projectName</code>, <code>screenCount</code>,
     * <code>dsCount</code>, <code>source</code>, <code>reifyURL</code>, <code>sourceLabel</code>, <code>loadedAt</code>, and
     * <code>instance</code> (the live Project object).
     *
     * @return loaded project records
     */
    public static native Map[] getLoadedProjects() /*-{
        var ret = $wnd.isc.Reify.getLoadedProjects();
        if(ret == null) return null;
        return @com.smartgwt.client.util.ConvertTo::arrayOfMap(Lcom/google/gwt/core/client/JavaScriptObject;)(ret);
    }-*/;


	/**
     * Return a {@link com.smartgwt.client.data.DataSource} bound to the live set of records returned by {@link
     * com.smartgwt.client.tools.Reify#getLoadedProjects getLoadedProjects()}.  The DS is <code>clientOnly</code> with
     * <code>cacheAllData:true</code>, so bound {@link com.smartgwt.client.widgets.grid.ListGrid ListGrids} update
     * automatically as projects are loaded and destroyed, and the DS supports synchronous {@link
     * com.smartgwt.client.data.DataSource#fetchDataSynchronous fetchDataSynchronous()}. <P> Returns the same DS instance on
     * every call.
     *
     * @return live discovery DS for projects
     */
    public static native DataSource getLoadedProjectsDS() /*-{
        var ret = $wnd.isc.Reify.getLoadedProjectsDS();
        if(ret == null) return null;
        return @com.smartgwt.client.data.DataSource::getOrCreateRef(Lcom/google/gwt/core/client/JavaScriptObject;)(ret);
    }-*/;


	/**
     * Return an Array of records describing every screen currently registered in the loaded-resource registry.  See {@link
     * com.smartgwt.client.tools.Reify#getLoadedProjects getLoadedProjects()} for the registry overview.
     *
     * @return loaded screen records
     */
    public static native Map[] getLoadedScreens() /*-{
        var ret = $wnd.isc.Reify.getLoadedScreens();
        if(ret == null) return null;
        return @com.smartgwt.client.util.ConvertTo::arrayOfMap(Lcom/google/gwt/core/client/JavaScriptObject;)(ret);
    }-*/;


	/**
     * Return a live clientOnly {@link com.smartgwt.client.data.DataSource} of loaded screen records.  See {@link
     * com.smartgwt.client.tools.Reify#getLoadedProjectsDS getLoadedProjectsDS()}.
     *
     * @return live discovery DS for screens
     */
    public static native DataSource getLoadedScreensDS() /*-{
        var ret = $wnd.isc.Reify.getLoadedScreensDS();
        if(ret == null) return null;
        return @com.smartgwt.client.data.DataSource::getOrCreateRef(Lcom/google/gwt/core/client/JavaScriptObject;)(ret);
    }-*/;


	/**
     * Exports or serializes the specified {@link com.smartgwt.client.data.DataSource DataSources} using the provided settings.
     * <P> The "reifyCSV" {@link com.smartgwt.client.util.MockDSExportSettings#getFormat format} generates comma-separated
     * values to paste into the DataSource creation wizard in {@link com.smartgwt.client.docs.ReifyForDevelopers Reify}.  The
     * use case for the other two formats is, if you have a Smart GWT application, and you plan to load {@link
     * com.smartgwt.client.data.MockDataSource MockDataSources} to enable people to add screens to your application using
     * Reify, you may want to test your application with the MockDataSources to ensure they have the right data to allow your
     * application to function (for example, that records in one MockDataSource that are related to another MockDataSource
     * match up).  Similarly, you may want to test any custom classes that you upload to Reify in a standalone file using
     * {@link com.smartgwt.client.data.MockDataSource MockDataSources}. <P> You can customize the <code>settings</code>, such
     * as {@link com.smartgwt.client.util.MockDSExportSettings#getNumRows numRows} (or {@link
     * com.smartgwt.client.util.MockDSExportSettings#getNumLevels numLevels} for tree DataSources) to keep the data volume
     * returned by the export low. When related DataSources are present, all related records will be included in the export,
     * even if <code>numRows</code> is exceeded. If this is too much data, {@link
     * com.smartgwt.client.util.MockDSExportSettings#getCriteria criteria} or {@link
     * com.smartgwt.client.util.MockDSExportSettings#getPerDSCriteria perDSCriteria} can be used to further restrict exported
     * records.  Note that <code>settings</code> supports an array of {@link
     * com.smartgwt.client.util.MockDSExportSettings#getRequestProperties requestProperties}, so that you can provide unique
     * configuration for each DataSource being exported, rather than only global configuration. <P> When exporting interlinked
     * DataSources, set {@link com.smartgwt.client.util.MockDSExportSettings#getFollowFKDepth
     * MockDSExportSettings.followFKDepth} to automatically discover additional DataSources reachable via foreignKey
     * relationships, so you don't have to manually enumerate every related DataSource. <P> <h4>Tree DataSource Handling</h4>
     * <P> When a DataSource has a self-referential {@link com.smartgwt.client.data.DataSourceField#getForeignKey foreignKey}
     * (a field that references the same DataSource), it is automatically detected as a {@link
     * com.smartgwt.client.docs.TreeDataBinding tree DataSource}.  Tree DataSources are fetched level-by-level: root nodes
     * first, then their children, up to {@link com.smartgwt.client.util.MockDSExportSettings#getNumLevels numLevels} deep. 
     * The {@link com.smartgwt.client.util.MockDSExportSettings#getTreeRoots treeRoots} setting can restrict which root nodes
     * are included. <P> Not every self-referential FK represents a tree hierarchy ? for example, a sales order might reference
     * the quotation (also an order) it was created from.  The automatic {@link
     * com.smartgwt.client.util.MockDSExportSettings#getMaxTreeRoots maxTreeRoots} check detects these cases by counting root
     * nodes before committing to tree-style fetching.  For explicit control, list such DataSources in {@link
     * com.smartgwt.client.util.MockDSExportSettings#getNonTreeDataSources MockDSExportSettings.nonTreeDataSources}. <P>
     * <h4>Large Database Export</h4> <P> When exporting from large production databases, the default behavior of batching all
     * DataSource fetches into a single queued request can exhaust database connection pools.  For these scenarios:<ul> <li>Set
     * {@link com.smartgwt.client.util.MockDSExportSettings#getSequentialFetching MockDSExportSettings.sequentialFetching} to
     * fetch one DataSource at a time instead of all at once. <li>Use {@link
     * com.smartgwt.client.util.MockDSExportSettings#getPerDSCriteria MockDSExportSettings.perDSCriteria} to narrow large
     * tables to relevant subsets (e.g. active records, recent dates). <li>The {@link
     * com.smartgwt.client.util.MockDSExportSettings#getMaxTreeRoots MockDSExportSettings.maxTreeRoots} default of 500
     * automatically prevents unbounded root-node queries on DataSources where a self-FK is not a real hierarchy. <li>For
     * DataSources you know are not trees, list them in {@link
     * com.smartgwt.client.util.MockDSExportSettings#getNonTreeDataSources MockDSExportSettings.nonTreeDataSources} to skip the
     * exploratory root-count query entirely.</ul> <P> Unless you need programmatic or expert control over the settings, you
     * will likely find it easier to use the "Reify Export" button in the {@link com.smartgwt.client.docs.DataSourcesTab
     * DataSources tab}, as when using that route, useful global and per-DataSource settings can be configured in an
     * intuitively-arranged popup dialog.
     * @param dsNames {@link com.smartgwt.client.data.DataSource#getID ID}s of the desired DataSources
     * @param callback called with the complete     export or serialization
     * @param settings controls format and what     records and metadata to include
     * @see com.smartgwt.client.tools.Reify#showMockDS
     */
    public static native void getMockDS(String[] dsNames, MockDSExportCallback callback, MockDSExportSettings settings) /*-{
        $wnd.isc.Reify.getMockDS(@com.smartgwt.client.util.JSOHelper::convertToJavaScriptArray([Ljava/lang/Object;)(dsNames), 
			$entry( function(allDSData, perDSData) { 
				if(callback!=null) callback.@com.smartgwt.client.callbacks.MockDSExportCallback::execute(Ljava/lang/String;[Ljava/lang/String;)(
					allDSData, 
					perDSData != null ? @com.smartgwt.client.util.ConvertTo::arrayOfString(Lcom/google/gwt/core/client/JavaScriptObject;)(perDSData) : null
				);
			}), settings.@com.smartgwt.client.core.DataClass::getJsObj()());
    }-*/;


	/**
     * Return a {@link com.smartgwt.client.data.DataSource} for browsing the list of projects in a Reify installation, suitable
     * for binding to a {@link com.smartgwt.client.widgets.grid.ListGrid}, {@link com.smartgwt.client.widgets.tree.TreeGrid},
     * {@link com.smartgwt.client.widgets.form.fields.SelectItem}, etc. <P> By default, the local server's Reify storage is
     * used.  Pass a {@link com.smartgwt.client.tools.ReifyDSSettings} object with <code>reifyURL</code> set to access a remote
     * Reify server (see {@link com.smartgwt.client.tools.Reify#defaultReifyURL defaultReifyURL}). <P> The DataSource is
     * delivered asynchronously via callback because the underlying DataSource definition may need to be loaded from the server
     * first.  Subsequent calls for the same target return the same DataSource instance.
     * @param callback called with <code>(DataSource ds)</code>                 ? the DataSource is null on failure.
     * See {@link com.smartgwt.client.docs.Callback Callback}
     * @param settings optional override settings
     */
    public static native void getProjectsDS(String callback, ReifyDSSettings settings) /*-{
        $wnd.isc.Reify.getProjectsDS(callback, settings.@com.smartgwt.client.core.DataClass::getJsObj()());
    }-*/;


	/**
     * Find all assets (projects, screens, DataSources) in the current page that are also stored in Reify.  This is an async
     * operation since it queries the Reify file storage.
     * @param callback called with (Object results) where results     has properties: projects (Array), screens (Array), dataSources    
     * (Array)
     */
    public static native void getReifyAssetsInPage(Function callback) /*-{
        $wnd.isc.Reify.getReifyAssetsInPage(
			$entry( function() { 
				if(callback!=null) callback.@com.smartgwt.client.core.Function::execute()(
				);
			}));
    }-*/;


	/**
     * Get a list of DataSources stored in Reify's DS storage.
     * @param callback called with (Array of String dsIds)
     */
    public static native void getReifyDataSources(Function callback) /*-{
        $wnd.isc.Reify.getReifyDataSources(
			$entry( function() { 
				if(callback!=null) callback.@com.smartgwt.client.core.Function::execute()(
				);
			}));
    }-*/;


	/**
     * Get a list of projects stored in Reify's project storage.
     * @param callback called with (Array of String projectNames)
     */
    public static native void getReifyProjects(Function callback) /*-{
        $wnd.isc.Reify.getReifyProjects(
			$entry( function() { 
				if(callback!=null) callback.@com.smartgwt.client.core.Function::execute()(
				);
			}));
    }-*/;


	/**
     * Get a list of screens stored in Reify's screen storage.
     * @param callback called with (Array of String screenNames)
     */
    public static native void getReifyScreens(Function callback) /*-{
        $wnd.isc.Reify.getReifyScreens(
			$entry( function() { 
				if(callback!=null) callback.@com.smartgwt.client.core.Function::execute()(
				);
			}));
    }-*/;


	/**
     * Determine which Reify project a screen belongs to, if any.  A screen belongs to a project if it is listed in the
     * project's screen list. This checks locally cached projects (loaded via {@link
     * com.smartgwt.client.rpc.RPCManager#loadProject RPCManager.loadProject()}).
     * @param screenName name of the screen
     *
     * @return the project containing the screen, or null
     */
    public static native Project getScreenProject(String screenName) /*-{
        var ret = $wnd.isc.Reify.getScreenProject(screenName);
        if(ret == null) return null;
        return @com.smartgwt.client.rpc.Project::getOrCreateRef(Lcom/google/gwt/core/client/JavaScriptObject;)(ret);
    }-*/;


	/**
     * Return a {@link com.smartgwt.client.data.DataSource} for browsing the list of screens in a Reify installation.  See
     * {@link com.smartgwt.client.tools.Reify#getProjectsDS getProjectsDS()} for behavior, settings, and remote-access details.
     * @param callback called with <code>(DataSource ds)</code>.
     * See {@link com.smartgwt.client.docs.Callback Callback}
     * @param settings optional override settings
     */
    public static native void getScreensDS(String callback, ReifyDSSettings settings) /*-{
        $wnd.isc.Reify.getScreensDS(callback, settings.@com.smartgwt.client.core.DataClass::getJsObj()());
    }-*/;


	/**
     * Check whether a DataSource is stored in Reify's DS storage (vbDataSources).
     * @param dataSourceId DataSource ID
     * @param callback called with (Boolean isStored)
     */
    public static native void isDataSourceInReify(String dataSourceId, Function callback) /*-{
        $wnd.isc.Reify.isDataSourceInReify(dataSourceId, 
			$entry( function() { 
				if(callback!=null) callback.@com.smartgwt.client.core.Function::execute()(
				);
			}));
    }-*/;


	/**
     * Check whether a project loaded via {@link com.smartgwt.client.rpc.RPCManager#loadProject RPCManager.loadProject()} is
     * stored in Reify's project storage (vbProjects).
     * @param projectName name of the project
     * @param callback called with (Boolean isStored)
     */
    public static native void isProjectInReify(String projectName, Function callback) /*-{
        $wnd.isc.Reify.isProjectInReify(projectName, 
			$entry( function() { 
				if(callback!=null) callback.@com.smartgwt.client.core.Function::execute()(
				);
			}));
    }-*/;


	/**
     * Check whether a screen is stored in Reify's screen storage (vbScreens).
     * @param screenName name of the screen
     * @param callback called with (Boolean isStored)
     */
    public static native void isScreenInReify(String screenName, Function callback) /*-{
        $wnd.isc.Reify.isScreenInReify(screenName, 
			$entry( function() { 
				if(callback!=null) callback.@com.smartgwt.client.core.Function::execute()(
				);
			}));
    }-*/;


	/**
     * Loads projects from the {@link com.smartgwt.client.docs.Reify} server specified by {@link
     * com.smartgwt.client.tools.Reify#serverURL serverURL} (or {@link com.smartgwt.client.rpc.LoadProjectSettings#getServerURL
     * LoadProjectSettings.serverURL}) using the  {@link com.smartgwt.client.docs.ServletDetails ProjectLoaderServlet},
     * reachable at the relative path {@link com.smartgwt.client.tools.Reify#projectLoaderPath projectLoaderPath} (or {@link
     * com.smartgwt.client.rpc.LoadProjectSettings#getProjectLoaderPath LoadProjectSettings.projectLoaderPath}) underneath the
     * server URL, and fires the given callback after the project has been cached.  When a project is loaded, all of its
     * DataSources and screens (except where explicitly overridden by settings) are also cached in the project. <P> See {@link
     * com.smartgwt.client.rpc.RPCManager#loadProject RPCManager.loadProject()} for further details.
     * @param projectNames Comma-separated string containing the names of                                           project(s) to load.
     * @param callback Callback for notification of completion of                                           project(s) loaded and screens
     * cached.
     * @param settings Settings applicable to the loadProject                                           operation.
     * @see com.smartgwt.client.tools.Reify
     */
    public static native void loadProject(String projectNames, LoadProjectCallback callback, LoadProjectSettings settings) /*-{
        $wnd.isc.Reify.loadProject(projectNames, 
			$entry( function(project, projects, rpcResponse) { 
				if(callback!=null) callback.@com.smartgwt.client.callbacks.LoadProjectCallback::execute(Lcom/smartgwt/client/rpc/Project;[Lcom/smartgwt/client/rpc/Project;Lcom/smartgwt/client/rpc/RPCResponse;)(
					project != null ? @com.smartgwt.client.rpc.Project::new(Lcom/google/gwt/core/client/JavaScriptObject;)(project) : null, 
					projects != null ? @com.smartgwt.client.util.ConvertTo::arrayOfProject(Lcom/google/gwt/core/client/JavaScriptObject;)(projects) : null, 
					@com.smartgwt.client.rpc.RPCResponse::new(Lcom/google/gwt/core/client/JavaScriptObject;)(rpcResponse)
				);
			}), settings.@com.smartgwt.client.core.DataClass::getJsObj()());
    }-*/;


	/**
     * Load the Reify editor, either inline in the current page or in a new browser window.  Returns a ReifyRemote via callback
     * that provides a uniform API for controlling and receiving notifications from the Reify instance regardless of how it was
     * loaded. <P> In <b>inline mode</b>, all required Reify modules are dynamically loaded into the current page via 
     * FileLoader.loadModules() and a Reify instance is created. <P> In <b>window mode</b>, Reify is opened in a new browser
     * tab. Communication uses <code>window.postMessage</code> by default (same-origin) or RealTime Messaging if <code>useRTM:
     * true</code> (cross-origin).
     * @param config configuration
     * @param callback called with a ReifyRemote instance
     */
    public static native void loadReify(ReifyLoadConfig config, Function callback) /*-{
        $wnd.isc.Reify.loadReify(config.@com.smartgwt.client.core.DataClass::getJsObj()(), 
			$entry( function() { 
				if(callback!=null) callback.@com.smartgwt.client.core.Function::execute()(
				);
			}));
    }-*/;


	/**
     * Loads a {@link com.smartgwt.client.rpc.Project} from a file on the server previously saved by {@link
     * com.smartgwt.client.tools.Reify#saveProject saveProject()}, without contacting a Reify server. <P> A saved project file
     * is a JSON envelope containing each screen and DataSource definition.  Each definition includes the JavaScript component
     * code (the <code>code</code> property) and, when the project was originally loaded with {@link
     * com.smartgwt.client.rpc.LoadProjectSettings#getIncludeXML includeXML:true}, the original XML source as well (the
     * <code>xml</code> property). Both representations are preserved through save/load round-trips. <P> The resulting {@link
     * com.smartgwt.client.rpc.Project} is cached the same way as one loaded via {@link
     * com.smartgwt.client.tools.Reify#loadProject loadProject()}, and screens can be created via {@link
     * com.smartgwt.client.rpc.Project#createScreen Project.createScreen()}.
     * @param path server path relative                 to the webRoot (e.g.                 "shared/myApp.proj.json")
     * @param callback called                 with the loaded {@link com.smartgwt.client.rpc.Project}
     * @see com.smartgwt.client.tools.Reify#saveProject
     */
    public static native void loadSavedProject(String path, LoadProjectCallback callback) /*-{
        $wnd.isc.Reify.loadSavedProject(path, 
			$entry( function(project, projects, rpcResponse) { 
				if(callback!=null) callback.@com.smartgwt.client.callbacks.LoadProjectCallback::execute(Lcom/smartgwt/client/rpc/Project;[Lcom/smartgwt/client/rpc/Project;Lcom/smartgwt/client/rpc/RPCResponse;)(
					project != null ? @com.smartgwt.client.rpc.Project::new(Lcom/google/gwt/core/client/JavaScriptObject;)(project) : null, 
					projects != null ? @com.smartgwt.client.util.ConvertTo::arrayOfProject(Lcom/google/gwt/core/client/JavaScriptObject;)(projects) : null, 
					@com.smartgwt.client.rpc.RPCResponse::new(Lcom/google/gwt/core/client/JavaScriptObject;)(rpcResponse)
				);
			}));
    }-*/;

	/**
     * Loads a {@link com.smartgwt.client.rpc.Project} from a file on the server previously saved by {@link
     * com.smartgwt.client.tools.Reify#saveProject saveProject()}, without contacting a Reify server. <P> A saved project file
     * is a JSON envelope containing each screen and DataSource definition.  Each definition includes the JavaScript component
     * code (the <code>code</code> property) and, when the project was originally loaded with {@link
     * com.smartgwt.client.rpc.LoadProjectSettings#getIncludeXML includeXML:true}, the original XML source as well (the
     * <code>xml</code> property). Both representations are preserved through save/load round-trips. <P> The resulting {@link
     * com.smartgwt.client.rpc.Project} is cached the same way as one loaded via {@link
     * com.smartgwt.client.tools.Reify#loadProject loadProject()}, and screens can be created via {@link
     * com.smartgwt.client.rpc.Project#createScreen Project.createScreen()}.
     * @param path server path relative                 to the webRoot (e.g.                 "shared/myApp.proj.json")
     * @param callback called                 with the loaded {@link com.smartgwt.client.rpc.Project}
     * @param settings optional settings for                   project loading
     * @see com.smartgwt.client.tools.Reify#saveProject
     */
    public static native void loadSavedProject(String path, LoadProjectCallback callback, LoadProjectSettings settings) /*-{
        $wnd.isc.Reify.loadSavedProject(path, 
			$entry( function(project, projects, rpcResponse) { 
				if(callback!=null) callback.@com.smartgwt.client.callbacks.LoadProjectCallback::execute(Lcom/smartgwt/client/rpc/Project;[Lcom/smartgwt/client/rpc/Project;Lcom/smartgwt/client/rpc/RPCResponse;)(
					project != null ? @com.smartgwt.client.rpc.Project::new(Lcom/google/gwt/core/client/JavaScriptObject;)(project) : null, 
					projects != null ? @com.smartgwt.client.util.ConvertTo::arrayOfProject(Lcom/google/gwt/core/client/JavaScriptObject;)(projects) : null, 
					@com.smartgwt.client.rpc.RPCResponse::new(Lcom/google/gwt/core/client/JavaScriptObject;)(rpcResponse)
				);
			}), settings == null ? null : settings.@com.smartgwt.client.core.DataClass::getJsObj()());
    }-*/;
	

	/**
     * Open a named screen in Reify for editing.  The screen must be stored in Reify's screen storage (vbScreens); if not, a
     * warning is logged and the call fails. <P> This is the screen equivalent of {@link
     * com.smartgwt.client.rpc.Project#loadInReify Project.loadInReify()} and {@link
     * com.smartgwt.client.data.DataSource#loadInReify DataSource.loadInReify()}.  Since screens are not first-class objects in
     * Smart GWT (they are Canvas hierarchies returned by {@link com.smartgwt.client.rpc.RPCManager#loadScreen
     * RPCManager.loadScreen()}), this method is on the Reify class rather than on a Screen instance.
     * @param screenName screen to edit
     * @param config optional config for     {@link com.smartgwt.client.tools.Reify#loadReify loadReify()}
     * @param callback called with ReifyRemote
     */
    public static native void loadScreenInReify(String screenName, ReifyLoadConfig config, Function callback) /*-{
        $wnd.isc.Reify.loadScreenInReify(screenName, config.@com.smartgwt.client.core.DataClass::getJsObj()(), 
			$entry( function() { 
				if(callback!=null) callback.@com.smartgwt.client.core.Function::execute()(
				);
			}));
    }-*/;


	/**
     * Add a {@link com.smartgwt.client.data.DataSource} reference to the loaded-resource registry.  Normally called from
     * {@link com.smartgwt.client.tools.Reify#registerLoadedProject registerLoadedProject()} for project-bundled DSes, but
     * available for application code that loads DSes outside the project flow.
     * @param dsName the DataSource's ID
     */
    public static native void registerLoadedDataSource(String dsName) /*-{
        $wnd.isc.Reify.registerLoadedDataSource(dsName);
    }-*/;

	/**
     * Add a {@link com.smartgwt.client.data.DataSource} reference to the loaded-resource registry.  Normally called from
     * {@link com.smartgwt.client.tools.Reify#registerLoadedProject registerLoadedProject()} for project-bundled DSes, but
     * available for application code that loads DSes outside the project flow.
     * @param dsName the DataSource's ID
     * @param info optional fields: <code>projectName</code>,    <code>source</code>, <code>reifyURL</code>,    <code>sourceLabel</code>
     */
    public static native void registerLoadedDataSource(String dsName, Map info) /*-{
        $wnd.isc.Reify.registerLoadedDataSource(dsName, info == null ? null : @com.smartgwt.client.util.JSOHelper::convertMapToJavascriptObject(Ljava/util/Map;)(info));
    }-*/;
	

	/**
     * Add a {@link com.smartgwt.client.rpc.Project} to the loaded-resource registry.  Called automatically by {@link
     * com.smartgwt.client.rpc.RPCManager#loadProject RPCManager.loadProject()} as projects come back from the server, and may
     * also be called by application code for projects assembled outside the normal load path (e.g. from local storage). <P>
     * Registration is idempotent: re-registering an already-known project just refreshes its record.  An automatic destroy
     * hook ensures the record is removed when the Project is destroyed.
     * @param project the Project instance to register
     */
    public static native void registerLoadedProject(Project project) /*-{
        $wnd.isc.Reify.registerLoadedProject(project == null ? null : project.@com.smartgwt.client.core.BaseClass::getOrCreateJsObj()());
    }-*/;

	/**
     * Add a {@link com.smartgwt.client.rpc.Project} to the loaded-resource registry.  Called automatically by {@link
     * com.smartgwt.client.rpc.RPCManager#loadProject RPCManager.loadProject()} as projects come back from the server, and may
     * also be called by application code for projects assembled outside the normal load path (e.g. from local storage). <P>
     * Registration is idempotent: re-registering an already-known project just refreshes its record.  An automatic destroy
     * hook ensures the record is removed when the Project is destroyed.
     * @param project the Project instance to register
     * @param sourceInfo optional override for source provenance    fields (<code>source</code>, <code>reifyURL</code>,   
     * <code>sourceLabel</code>); defaults derived from    {@link com.smartgwt.client.tools.Reify#defaultReifyURL
     * defaultReifyURL}
     */
    public static native void registerLoadedProject(Project project, Map sourceInfo) /*-{
        $wnd.isc.Reify.registerLoadedProject(project == null ? null : project.@com.smartgwt.client.core.BaseClass::getOrCreateJsObj()(), sourceInfo == null ? null : @com.smartgwt.client.util.JSOHelper::convertMapToJavascriptObject(Ljava/util/Map;)(sourceInfo));
    }-*/;
	

	/**
     * Add a screen Canvas instance to the loaded-resource registry. Called automatically by {@link
     * com.smartgwt.client.rpc.RPCManager#loadScreen RPCManager.loadScreen()} (when no project is involved) and by {@link
     * com.smartgwt.client.rpc.Project#createScreen Project.createScreen()} (which both replaces the project's
     * screen-definition record with one that points at the live Canvas, and arranges for cleanup when the Canvas is
     * destroyed).
     * @param canvas the screen's top-level Canvas instance
     */
    public static native void registerLoadedScreen(Canvas canvas) /*-{
        $wnd.isc.Reify.registerLoadedScreen(canvas == null ? null : canvas.@com.smartgwt.client.widgets.BaseWidget::getOrCreateJsObj()());
    }-*/;

	/**
     * Add a screen Canvas instance to the loaded-resource registry. Called automatically by {@link
     * com.smartgwt.client.rpc.RPCManager#loadScreen RPCManager.loadScreen()} (when no project is involved) and by {@link
     * com.smartgwt.client.rpc.Project#createScreen Project.createScreen()} (which both replaces the project's
     * screen-definition record with one that points at the live Canvas, and arranges for cleanup when the Canvas is
     * destroyed).
     * @param canvas the screen's top-level Canvas instance
     * @param info optional fields:    <code>screenName</code>, <code>projectName</code>,    <code>source</code>, <code>reifyURL</code>,   
     * <code>sourceLabel</code>
     */
    public static native void registerLoadedScreen(Canvas canvas, Map info) /*-{
        $wnd.isc.Reify.registerLoadedScreen(canvas == null ? null : canvas.@com.smartgwt.client.widgets.BaseWidget::getOrCreateJsObj()(), info == null ? null : @com.smartgwt.client.util.JSOHelper::convertMapToJavascriptObject(Ljava/util/Map;)(info));
    }-*/;
	

	/**
     * Saves a loaded {@link com.smartgwt.client.rpc.Project} to a file on
     *  the server, using the <code>saveFile</code>
     *  built-in RPC.  The file can later be loaded
     *  via {@link com.smartgwt.client.tools.Reify#loadSavedProject loadSavedProject()} to
     *  recreate the project without contacting a
     *  Reify server.
     *  <P>
     *  By default, the saved format is determined
     *  by how the project was loaded.  If the
     *  project was loaded with
     *  {@link com.smartgwt.client.rpc.LoadProjectSettings#getIncludeXML includeXML:true}, only the original XML
     *  definitions are saved &mdash; these are the
     *  verbatim strings from the Reify server, with
     *  no re-serialization or round-tripping.
     *  Otherwise, the JavaScript component code is
     *  saved.
     *  <P>
     *  The optional <code>format</code> parameter
     *  overrides this default:
     *  <ul>
     *  <li><b>"json"</b> &ndash; saves only the
     *      JavaScript <code>code</code>
     *      representation</li>
     *  <li><b>"xml"</b> &ndash; saves only the
     *      <code>xml</code> representation.
     *      Requires
     *      {@link com.smartgwt.client.rpc.LoadProjectSettings#getIncludeXML includeXML:true} to have been set when
     *      the project was loaded.</li>
     *  <li><b>"both"</b> &ndash; saves both
     *      <code>code</code> and <code>xml</code>
     *      (when present)</li>
     *  </ul>
     *  <P>
     *  Note: {@link com.smartgwt.client.rpc.Project#createScreen Project.createScreen()} requires
     *  the <code>code</code> property.  Files saved
     *  with only <code>xml</code> (the default when
     *  <code>includeXML</code> was used, or format
     *  "xml") cannot be loaded via
     *  {@link com.smartgwt.client.tools.Reify#loadSavedProject loadSavedProject()} for screen
     *  creation.  Use format "both" or "json" to
     *  produce a file suitable for
     *  {@link com.smartgwt.client.tools.Reify#loadSavedProject loadSavedProject()}.
     *  <P>
     *  The <code>saveFile</code> built-in method
     *  must be enabled in
     *  <code>server.properties</code>:
     *  <pre>
     *  RPCManager.enabledBuiltinMethods: saveFile
     *  </pre>
     * 
     * 
     * @param project a loaded project
     * @param path server path relative                 to the webRoot (e.g.                 "shared/myApp.proj.json")
     * @see com.smartgwt.client.tools.Reify#loadSavedProject
     */
    public static native void saveProject(Project project, String path) /*-{
        $wnd.isc.Reify.saveProject(project == null ? null : project.@com.smartgwt.client.core.BaseClass::getOrCreateJsObj()(), path);
    }-*/;

    /**
     * See {@link Reify#saveProject(com.smartgwt.client.rpc.Project, java.lang.String, com.smartgwt.client.data.DSCallback, java.lang.String) saveProject()}
     */
    public static void saveProject(Project project, String path, DSCallback callback){
        saveProject(project, path, callback, null);
    }

	/**
     * Saves a loaded {@link com.smartgwt.client.rpc.Project} to a file on
     *  the server, using the <code>saveFile</code>
     *  built-in RPC.  The file can later be loaded
     *  via {@link com.smartgwt.client.tools.Reify#loadSavedProject loadSavedProject()} to
     *  recreate the project without contacting a
     *  Reify server.
     *  <P>
     *  By default, the saved format is determined
     *  by how the project was loaded.  If the
     *  project was loaded with
     *  {@link com.smartgwt.client.rpc.LoadProjectSettings#getIncludeXML includeXML:true}, only the original XML
     *  definitions are saved &mdash; these are the
     *  verbatim strings from the Reify server, with
     *  no re-serialization or round-tripping.
     *  Otherwise, the JavaScript component code is
     *  saved.
     *  <P>
     *  The optional <code>format</code> parameter
     *  overrides this default:
     *  <ul>
     *  <li><b>"json"</b> &ndash; saves only the
     *      JavaScript <code>code</code>
     *      representation</li>
     *  <li><b>"xml"</b> &ndash; saves only the
     *      <code>xml</code> representation.
     *      Requires
     *      {@link com.smartgwt.client.rpc.LoadProjectSettings#getIncludeXML includeXML:true} to have been set when
     *      the project was loaded.</li>
     *  <li><b>"both"</b> &ndash; saves both
     *      <code>code</code> and <code>xml</code>
     *      (when present)</li>
     *  </ul>
     *  <P>
     *  Note: {@link com.smartgwt.client.rpc.Project#createScreen Project.createScreen()} requires
     *  the <code>code</code> property.  Files saved
     *  with only <code>xml</code> (the default when
     *  <code>includeXML</code> was used, or format
     *  "xml") cannot be loaded via
     *  {@link com.smartgwt.client.tools.Reify#loadSavedProject loadSavedProject()} for screen
     *  creation.  Use format "both" or "json" to
     *  produce a file suitable for
     *  {@link com.smartgwt.client.tools.Reify#loadSavedProject loadSavedProject()}.
     *  <P>
     *  The <code>saveFile</code> built-in method
     *  must be enabled in
     *  <code>server.properties</code>:
     *  <pre>
     *  RPCManager.enabledBuiltinMethods: saveFile
     *  </pre>
     * 
     * 
     * @param project a loaded project
     * @param path server path relative                 to the webRoot (e.g.                 "shared/myApp.proj.json")
     * @param callback called on                   completion
     * @param format "json", "xml",                   "both", or null for                   auto-detect
     * @see com.smartgwt.client.tools.Reify#loadSavedProject
     */
    public static native void saveProject(Project project, String path, DSCallback callback, String format) /*-{
        $wnd.isc.Reify.saveProject(project == null ? null : project.@com.smartgwt.client.core.BaseClass::getOrCreateJsObj()(), path, 
			$entry( function(dsResponse, data, dsRequest) { 
				if(callback!=null) callback.@com.smartgwt.client.data.DSCallback::execute(Lcom/smartgwt/client/data/DSResponse;Ljava/lang/Object;Lcom/smartgwt/client/data/DSRequest;)(
					@com.smartgwt.client.data.DSResponse::new(Lcom/google/gwt/core/client/JavaScriptObject;)(dsResponse), 
					data, 
					@com.smartgwt.client.data.DSRequest::new(Lcom/google/gwt/core/client/JavaScriptObject;)(dsRequest)
				);
			}), format);
    }-*/;
	

	/**
     * Save a project definition to Reify's project storage (vbProjects).  <code>projectXml</code> must be valid Reify project
     * XML as produced by <code>ReifyProject.xmlSerialize()</code>.
     * @param projectName project name
     * @param projectXml project XML content
     */
    public static native void saveProjectFile(String projectName, String projectXml) /*-{
        $wnd.isc.Reify.saveProjectFile(projectName, projectXml);
    }-*/;

	/**
     * Save a project definition to Reify's project storage (vbProjects).  <code>projectXml</code> must be valid Reify project
     * XML as produced by <code>ReifyProject.xmlSerialize()</code>.
     * @param projectName project name
     * @param projectXml project XML content
     * @param callback called with     (DSResponse dsResponse, Object data)
     */
    public static native void saveProjectFile(String projectName, String projectXml, Function callback) /*-{
        $wnd.isc.Reify.saveProjectFile(projectName, projectXml, 
			$entry( function() { 
				if(callback!=null) callback.@com.smartgwt.client.core.Function::execute()(
				);
			}));
    }-*/;
	

	/**
     * Save screen content (XML or JSON) to Reify's screen storage (vbScreens).  This makes the screen available for use in
     * Reify projects via {@link com.smartgwt.client.tools.Reify#loadReify loadReify()} or {@link
     * com.smartgwt.client.tools.Reify#loadScreenInReify loadScreenInReify()}.
     * @param screenName name for the screen
     * @param screenContents screen XML or JSON content,     as produced by {@link com.smartgwt.client.tools.EditContext#serializeAllEditNodes
     * EditContext.serializeAllEditNodes()}
     */
    public static native void saveScreen(String screenName, String screenContents) /*-{
        $wnd.isc.Reify.saveScreen(screenName, screenContents);
    }-*/;

	/**
     * Save screen content (XML or JSON) to Reify's screen storage (vbScreens).  This makes the screen available for use in
     * Reify projects via {@link com.smartgwt.client.tools.Reify#loadReify loadReify()} or {@link
     * com.smartgwt.client.tools.Reify#loadScreenInReify loadScreenInReify()}.
     * @param screenName name for the screen
     * @param screenContents screen XML or JSON content,     as produced by {@link com.smartgwt.client.tools.EditContext#serializeAllEditNodes
     * EditContext.serializeAllEditNodes()}
     * @param callback called with     (DSResponse dsResponse, Object data)
     */
    public static native void saveScreen(String screenName, String screenContents, Function callback) /*-{
        $wnd.isc.Reify.saveScreen(screenName, screenContents, 
			$entry( function() { 
				if(callback!=null) callback.@com.smartgwt.client.core.Function::execute()(
				);
			}));
    }-*/;
	

	/**
     * Reassign the key combination that activates the {@link com.smartgwt.client.tools.Reify#enableOverlay overlay view}. <P>
     * Pass a {@link com.smartgwt.client.core.KeyIdentifier} object.  When <code>keyName</code> is present the binding is a
     * press-to-toggle shortcut; when absent only modifiers are checked and the overlay uses <b>hold-to-show</b> mode (appears
     * while held, auto-dismisses on release). <P> A plain String string (e.g. <code>"F2"</code>) is also accepted and treated
     * as a toggle shortcut.
     * @param key new key binding.
     * See {@link com.smartgwt.client.docs.KeyName KeyName}
     * @see com.smartgwt.client.docs.KeyName KeyName
     */
    public static native void setOverlayKey(String key) /*-{
        $wnd.isc.Reify.setOverlayKey(key);
    }-*/;

	/**
     * Reassign the key combination that activates the {@link com.smartgwt.client.tools.Reify#enableOverlay overlay view}. <P>
     * Pass a {@link com.smartgwt.client.core.KeyIdentifier} object.  When <code>keyName</code> is present the binding is a
     * press-to-toggle shortcut; when absent only modifiers are checked and the overlay uses <b>hold-to-show</b> mode (appears
     * while held, auto-dismisses on release). <P> A plain String string (e.g. <code>"F2"</code>) is also accepted and treated
     * as a toggle shortcut.
     * @param key new key binding.
     * See {@link com.smartgwt.client.docs.KeyName KeyName}
     * @see com.smartgwt.client.docs.KeyName KeyName
     */
    public static native void setOverlayKey(KeyIdentifier key) /*-{
        $wnd.isc.Reify.setOverlayKey(key.@com.smartgwt.client.core.DataClass::getJsObj()());
    }-*/;


	/**
     * Setter for {@link com.smartgwt.client.tools.Reify#password password}.
     * @param password 
     */
    public static native void setPassword(String password) /*-{
        $wnd.isc.Reify.setPassword(password);
    }-*/;


	/**
     * Setter for {@link com.smartgwt.client.tools.Reify#projectLoaderPath projectLoaderPath}.
     * @param path 
     */
    public static native void setProjectLoaderPath(String path) /*-{
        $wnd.isc.Reify.setProjectLoaderPath(path);
    }-*/;


	/**
     * Setter for {@link com.smartgwt.client.tools.Reify#serverURL serverURL}.
     * @param serverURL .
     * See {@link com.smartgwt.client.docs.URL URL}
     * @see com.smartgwt.client.docs.URL URL
     */
    public static native void setServerURL(String serverURL) /*-{
        $wnd.isc.Reify.setServerURL(serverURL);
    }-*/;


	/**
     * Setter for {@link com.smartgwt.client.tools.Reify#userName userName}.
     * @param userName 
     */
    public static native void setUserName(String userName) /*-{
        $wnd.isc.Reify.setUserName(userName);
    }-*/;


	/**
     * Shows the result of running {@link com.smartgwt.client.tools.Reify#getMockDS getMockDS()} in a  modal window so it can
     * be copied and pasted as needed into {@link com.smartgwt.client.docs.ReifyForDevelopers Reify} or elsewhere. <P> Note
     * that the callback is fired when the window is closed, not when it's populated.
     * @param dsNames {@link com.smartgwt.client.data.DataSource#getID ID}s of the desired                                          
     * DataSources
     * @param callback called with the complete export or serialization
     * @param settings controls format and what records and metadata to                                        include
     */
    public static native void showMockDS(String[] dsNames, MockDSExportCallback callback, MockDSExportSettings settings) /*-{
        $wnd.isc.Reify.showMockDS(@com.smartgwt.client.util.JSOHelper::convertToJavaScriptArray([Ljava/lang/Object;)(dsNames), 
			$entry( function(allDSData, perDSData) { 
				if(callback!=null) callback.@com.smartgwt.client.callbacks.MockDSExportCallback::execute(Ljava/lang/String;[Ljava/lang/String;)(
					allDSData, 
					perDSData != null ? @com.smartgwt.client.util.ConvertTo::arrayOfString(Lcom/google/gwt/core/client/JavaScriptObject;)(perDSData) : null
				);
			}), settings.@com.smartgwt.client.core.DataClass::getJsObj()());
    }-*/;


	/**
     * Show the overlay view with optional dismiss behaviour. Greys out the page and draws a colored frame plus action icons
     * around every loaded Reify screen.  Idempotent.
     * @see com.smartgwt.client.tools.Reify#enableOverlay
     */
    public static native void showOverlay() /*-{
        $wnd.isc.Reify.showOverlay();
    }-*/;

	/**
     * Show the overlay view with optional dismiss behaviour. Greys out the page and draws a colored frame plus action icons
     * around every loaded Reify screen.  Idempotent.
     * @param settings optional dismiss and   behaviour configuration
     * @see com.smartgwt.client.tools.Reify#enableOverlay
     */
    public static native void showOverlay(OverlaySettings settings) /*-{
        $wnd.isc.Reify.showOverlay(settings == null ? null : settings.@com.smartgwt.client.core.DataClass::getJsObj()());
    }-*/;
	

	/**
     * Show the {@link com.smartgwt.client.tools.Reify#enableOverlay overlay view} if it is hidden, or hide it if it is
     * showing.
     */
    public static native void toggleOverlay() /*-{
        $wnd.isc.Reify.toggleOverlay();
    }-*/;


	/**
     * Remove a DataSource entry from the loaded-resource registry.
     * @param dsName the DataSource's ID
     */
    public static native void unregisterLoadedDataSource(String dsName) /*-{
        $wnd.isc.Reify.unregisterLoadedDataSource(dsName);
    }-*/;


	/**
     * Remove a {@link com.smartgwt.client.rpc.Project} from the loaded-resource registry, along with all of its screens and
     * DataSources.  Called automatically by {@link com.smartgwt.client.rpc.Project#destroy Project.destroy()}.
     * @param project the Project to remove
     */
    public static native void unregisterLoadedProject(Project project) /*-{
        $wnd.isc.Reify.unregisterLoadedProject(project == null ? null : project.@com.smartgwt.client.core.BaseClass::getOrCreateJsObj()());
    }-*/;


	/**
     * Remove a screen from the loaded-resource registry.  Called automatically when a registered screen Canvas is destroyed
     * (via an observation of {@link com.smartgwt.client.widgets.Canvas#destroy Canvas.destroy()}).
     * @param canvas the screen's top-level Canvas instance
     */
    public static native void unregisterLoadedScreen(Canvas canvas) /*-{
        $wnd.isc.Reify.unregisterLoadedScreen(canvas == null ? null : canvas.@com.smartgwt.client.widgets.BaseWidget::getOrCreateJsObj()());
    }-*/;


    /** 
     * Class level method to set the default properties of this class.  If set, then all
     * existing and subsequently created instances of this class will automatically have
     * default properties corresponding to
     * the properties set on the SmartGWT class instance passed to this function before its
     * underlying SmartClient JS object was created.
     * This is a powerful feature that eliminates the need for users to create a separate
     * hierarchy of subclasses that only alter the default properties of this class. Can also
     * be used for skinning / styling purposes.  <P> <b>Note:</b> This method is intended for
     * setting default attributes only and will affect all instances of the underlying class
     * (including those automatically generated in JavaScript).  This method should not be used
     * to apply standard EventHandlers or override methods for a class - use a custom subclass
     * instead.  Calling this method after instances have been created can result in undefined
     * behavior, since it bypasses any setters and a class instance may have already examined 
     * a particular property and not be expecting any changes through this route.
     *
     * @param reifyProperties properties that should be used as new defaults when instances of this class are created
     * @see com.smartgwt.client.docs.SGWTProperties
     */
    public static native void setDefaultProperties(Reify reifyProperties) /*-{
        if (reifyProperties.@com.smartgwt.client.widgets.BaseWidget::isCreated()()) {
            @com.smartgwt.client.util.ConfigUtil::warnOfPreConfigInstantiation(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Class;)(Reify.@java.lang.Object::getClass()(), "setDefaultProperties", reifyProperties.@java.lang.Object::getClass()());
        }
        reifyProperties.@com.smartgwt.client.widgets.BaseWidget::setConfigOnly(Z)(true);
    	var properties = reifyProperties.@com.smartgwt.client.widgets.BaseWidget::getConfig()();
        properties = @com.smartgwt.client.util.JSOHelper::cleanProperties(Lcom/google/gwt/core/client/JavaScriptObject;Z)(properties,true);
        $wnd.isc.Reify.addProperties(properties);
    }-*/;

    // ***********************************************************



    public JavaScriptObject getOrCreateJsObj() {
        String missing = this.requiredModulesMissing();
        if (missing != null) {
            SC.logWarn("ERROR: The following modules are required by Reify and " +
                       "must be loaded in your bootstrap HTML file: " + missing);
        return null;
        }
        return super.getOrCreateJsObj();
    }

    private native String requiredModulesMissing() /*-{
        var missing,
            required = {
                ComponentEditor: "ISC_Tools.js",
                AdminConsole: "ISC_AdminConsole.js",
                DocViewer: "ISC_DocViewer.js",
                FileLoader: "ISC_FileLoader.js",
                FileBrowser: "ISC_FileBrowser.js",
                Reify: "ISC_Reify.js"
            };
        
        for (var module in required) {
            if (!$wnd.isc[module]) {
                missing = missing ? missing + ", " + required[module] : required[module];
            }
        }
        return missing;
    }-*/;


    // ------------------------------------------
    // Handle Post-create customization callbacks

    protected void onInit() {
		super.onInit();

        // widget created; call hook
        afterCreateHook();        

        // handle autoDraw:true case
        if (isDrawn()) {
            afterDrawHook();
            return;
        }    

        // otherwise, hook later draw
        addDrawHandler(new DrawHandler() {
            public void onDraw(DrawEvent event) {
                ((Reify)event.getFiringCanvas()).afterDrawHook();
            }
        });
    }

    private native void afterCreateHook() /*-{
        if ($wnd.window.hookAfterVBCreate) {
            $wnd.window.hookAfterVBCreate();
        }
    }-*/;

    private native void afterDrawHook() /*-{
        if ($wnd.window.hookAfterVBDraw) {
            $wnd.window.hookAfterVBDraw();
        }
    }-*/;



    /**
     * Setter implementing the {@link com.smartgwt.client.core.LogicalStructure} interface,
     * which supports Eclipse's logical structure debugging facility.
     */
    public LogicalStructureObject setLogicalStructure(ReifyLogicalStructure s) {
        super.setLogicalStructure(s);
        try {
            s.projectDataSourceAsDataSource = getProjectDataSource();
        } catch (Throwable t) {
            s.logicalStructureErrors += "Reify.projectDataSourceAsDataSource:" + t.getMessage() + "\n";
        }
        try {
            s.projectDataSourceAsString = getAttributeAsString("projectDataSource");
        } catch (Throwable t) {
            s.logicalStructureErrors += "Reify.projectDataSourceAsString:" + t.getMessage() + "\n";
        }
        return s;
    }

    /**
     * Getter implementing the {@link com.smartgwt.client.core.LogicalStructure} interface,
     * which supports Eclipse's logical structure debugging facility.
     */
    public LogicalStructureObject getLogicalStructure() {
        ReifyLogicalStructure s = new ReifyLogicalStructure();
        setLogicalStructure(s);
        return s;
    }
}
