API Docs for:
Show:

File: XholonJsApi.js

/**
 * <h3>Xholon JavaScript API</h3>
 * <p>This is the JavaScript application programming interface (API)
 * for Xholon (http://www.primordion.com/Xholon/gwt/) version 0.9.1. (July 7, 2014)</p>
 * <p>It's a wrapper around the Xholon Google Web Toolkit (GWT) (http://www.gwtproject.org/) Java code.
 * Note that GWT compiles all of the Java code to optimized JavaScript.</p>
 * <p>The online JavaScript documentation is produced with the help of YuiDoc,
 * and the comment blocks in this file must be in YuiDoc-compatible format (http://yui.github.io/yuidoc/).</p>
 <p>Updated August 14, 2025 by Ken</p>
 * <p>The API is Copyright (C) 2014, 2025 Ken Webb, and is released under the MIT License.</p>
 * 
 * @module XholonJsApi
 */

/**
 * These methods apply to the top level of the Xholon application.
 * All of the methods in this class MUST be preceeded by "$wnd.xh." (ex: "$wnd.xh.app();")
 * if they are run from within the Xholon application. The "$wnd." is a GWT requirement.
 * They MUST be preceeded by "xh." (ex: "xh.app();") if they are run using a developer's tool such as Firebug
 * or Developer Tools.
 *
 * @class xh
 * @constructor
 */
$wnd.xh = {};

$wnd.xh.html = new Object();

/**
 * Get the single app-specific IApplication instance.
 * @method app
 * @return {IApplication} An instance of a subclass of org.primordion.xholon.app.Application.
 * @example
 *     var app = $wnd.xh.app();
 */
$wnd.xh.app = $entry(function() {
  return app.@org.primordion.xholon.app.Application::getApp()();
});

/**
 * Get the app-specific root of the composite structure hierarchy.
 * @method root
 * @return {IXholon} An instance of a subclass of org.primordion.xholon.base.Xholon.
 * @example
 *     var root = $wnd.xh.root();
 */
$wnd.xh.root = $entry(function() {
  return app.@org.primordion.xholon.app.Application::getRoot()();
});

/**
 * Log all attribute name/value pairs (JavaScript properties) of a node to the browser console.
 * This is mostly intended for debugging.
 * @method attrs
 * @param {IXholon} node An IXholon node.
 * @example
 *     var node = $wnd.xh.root();
 *     $wnd.xh.attrs(node);
 */
$wnd.xh.attrs = $entry(function(node) {
  if ($wnd.console) {
    $wnd.console.log("Properties of " + node);
    for (var prop in node) {
      var pname = prop;
      var pval = node[pname];
      if (typeof pval != "function") {
        $wnd.console.log(pname + ": " + pval);
      }
    }
  }
});

/**
 * Evaluate an XPath 1.0 expression.
 * @method xpath
 * @param {String} expression An XPath 1.0 String expression (ex: "ancestor::HelloWorldSystem/World");
 * @param {IXholon} node An IXholon node.
 * @return {IXholon} An IXholon node, or null.
 * @example
 *     var node = $wnd.xh.root().first(); // get the Hello node
 *     $wnd.xh.xpath("ancestor::HelloWorldSystem/World", node);
 */
$wnd.xh.xpath = $entry(function(expression, node) {
  return @org.client.XholonJsApi::xpath(Ljava/lang/String;Lorg/primordion/xholon/base/IXholon;)(expression, node);
});



/**
 * Get an XPath 1.0 compliant expression that uniquely identifies a path from an ancestor node to a descendant node.
 * @method xpathExpr
 * @param {IXholon} descendant A Xholon node that is a descendant of ancestor.
 * @param {IXholon} ancestor A Xholon node that is an ancestor of descendant.
 * @return {String} 
 * @example
 *     console.log(xh.xpathExpr($wnd.xh.root().first(), xh.root())); // "HelloWorldSystem/Hello"
 * @example
 *     var ancestor = $wnd.xh.root().first().first(); // City
 *     var descendant = ancestor.xpath("School[@roleName='Hilson']");
 *     $wnd.console.log($wnd.xh.xpathExpr(descendant, ancestor)); // "City/School[@roleName='Hilson']"
 */
$wnd.xh.xpathExpr = $entry(function(descendant, ancestor)) {
  return @org.client.XholonJsApi::xpathExpr(Lorg/primordion/xholon/base/IXholon;Lorg/primordion/xholon/base/IXholon;)(descendant, ancestor);
}


/**
 * Get a Xholon Service.
 * @method service
 * @param {String} serviceName The name of a service (ex: "TimelineService").
 * @return {IXholon} An IXholon node, or null.
 * @example
 *     var service = $wnd.xh.service("TimelineService");
 *     console.log(service);
 */
$wnd.xh.service = $entry(function(serviceName) {
  return app.@org.primordion.xholon.app.Application::getService(Ljava/lang/String;)(serviceName);
});

/**
 * Display a list of names of services and their activation status, in the out tab.
 * @method services
 * @example
 *     $wnd.xh.services();
 */
$wnd.xh.services = $entry(function() {
  var serviceLocator = app.@org.primordion.xholon.app.Application::getService(Ljava/lang/String;)("ServiceLocatorService");
  serviceLocator.@org.primordion.xholon.base.IXholon::doAction(Ljava/lang/String;)("Show activation statuses");
});

/**
 * Get or set the value of an application parameter.
 * @method param
 * @param {String} pName The name of the parameter.
 * @param {String} [pValue] The value of the parameter.
 * @return {String} The value of the parameter, or null, or undefined.
 * @example
 *     // set the interval between time steps as 200 milliseconds
 *     // show the before and after values in the browser console
 *     console.log($wnd.xh.param("TimeStepInterval"));
 *     $wnd.xh.param("TimeStepInterval", "200");
 *     console.log($wnd.xh.param("TimeStepInterval"));
 */
$wnd.xh.param = $entry(function(pName, pValue) {
  if (pValue === undefined) {
    return app.@org.primordion.xholon.app.Application::getParam(Ljava/lang/String;)(pName)
  }
  else {
    app.@org.primordion.xholon.app.Application::setParam(Ljava/lang/String;Ljava/lang/String;)(pName, pValue);
  }
});

/**
 * Set controller state.
 * The example below sets the controller state to CS_STEPPING,
 * which causes the app to move forward one timestep, and then go into CS_PAUSE state.
 * @method state
 * @param {Number} controllerState 5 is currently the only useful value.
 * @example
 *     $wnd.xh.state(5);
 */
$wnd.xh.state = $entry(function(controllerState) {
  app.@org.primordion.xholon.app.Application::setControllerState(I)(controllerState);
});

/**
 * Require a single named JavaScript library.
 * If the script is located in the Xholon application library,
 * then only the scriptName needs to be provided.
 * @method require
 * @param {String} scriptName The name of a script.
 * @param {String} [scriptPath] The URL for the script.
 * @example
 *     $wnd.xh.require("d3.v2.min.js");
 * @example
 *     $wnd.xh.require("three.min.js", "http://threejs.org/build/");
 */
$wnd.xh.require = $entry(function(scriptName, scriptPath) {
  @org.primordion.xholon.io.gwt.HtmlScriptHelper::requireScript(Ljava/lang/String;Ljava/lang/String;)(scriptName, scriptPath)
});

/**
 * Run the Xholon JavaScript API unit tests, using QUnit.
 * The tests are intended to run inside the Furcifer app:
 *   http://www.primordion.com/Xholon/gwt/XholonQUnit.html?app=Furcifer&gui=clsc
 * See also the Information page for the Furcifer app (Help > Information).
 * @method test
 * @example
 *     $wnd.xh.test();
 */
$wnd.xh.test = $entry(function() {
  if ($wnd.QUnit) {
    $wnd.QUnit.config.autostart = false;
    $wnd.xh.require("XholonJsApiUnitTests.js");
  }
});

/**
 * Toggle the visibility of an existing HTML element, typically a div that starts with "xh".
 * @method html.toggle
 * @param {String} elementId An HTML element id.
 * @example
 *     $wnd.xh.html.toggle("xhgui");
 */
$wnd.xh.html.toggle = $entry(function(elementId) {
  @org.client.HtmlElementCache::toggleElementDisplay(Ljava/lang/String;)(elementId);
});

/**
 * Get an array of top-level "xh" element id's.
 * @method html.xhElements
 * @return {String} a comma-delimited list
 *   (ex: "xhtop,xhgui,xhappspecific,xhconsole,xhtabs,xhchart,xhcanvas,xhgraph,xhsvg,xhimg").
 * @example
 *     $wnd.xh.html.xhElements();
 */
$wnd.xh.html.xhElements = $entry(function() {
  return @org.client.HtmlElementCache::getTopLevelElementNames()();
});

/**
 * Generate a popup on the browser HTML page.
 * @method html.popup
 * @param {String} title 
 * @param {String} htmlText 
 * @param {boolean} autoHide
 * @param {boolean} modal
 * @param {Intger} left
 * @param {Integer} top
 * @return 
 * @example
 *     $wnd.xh.html.popup("Title", "<div><p>Hello Popup</p></div>");
 */
$wnd.xh.html.popup = $entry(function(title, htmlText, autoHide, modal, left, top) {})

/**
 * Get a URL search param from the browser.
 * For example, if the URL line includes the text "&one=two", then asking for param "one" will return "two".
 * @method html.urlparam
 * @param {String} a URL param
 * @return {String} a value, or null
 * @example
 *     console.log($wnd.xh.html.urlparam("one")); // "two"
 */
$wnd.xh.html.urlparam = $entry(function(searchParam) {})

/**
 * Select a tab in #xhtabs .
 * @method selectTab
 * @param {Number} index the XXholon tab index
 * @return 
 * @example
 *     $wnd.xh.html.selectTab(0); // "out"
 *     $wnd.xh.html.selectTab(1); // "clipboard"
 *     $wnd.xh.html.selectTab(2); // "notes"
 */
$wnd.xh.html.selectTab = $entry(function(index) {})

/**
 * Set styles for elements in the HTML page.
 * @method css.style
 * @param {Strong} content
 * @example
 *     $wnd.xh.css.style(".d3cpnode circle {stroke-width: 0px;}");
 */
$wnd.xh.css.style = $entry(function(content) {})

/**
 * Export a node and its subtree to an external format.
 * Because "export" is a JS keyword, we use "xport" instead.
 * @method xport
 * @param {String} formatName The name of an external format (ex: "MindMap").
 * @param {IXholon} node An IXholon node.
 * @param {String} [efParams] A JSON-formatted string containing one or more key/value pairs.
 *   To determine the possible parameters for a given external format,
 *   look at the efParams object in each ef source file.
 * @example
 *     var root = $wnd.xh.root();
 *     $wnd.xh.xport("MindMap", root);
 *     $wnd.xh.xport("Yaml", root);
 *     $wnd.xh.xport("_other,Newick", root);
 *     $wnd.xh.xport("_xholon,Xhn", root);
 *     $wnd.xh.xport("_d3,CirclePack", root);
 *     $wnd.xh.xport("Graphviz", root, '{"layout":"neato"}');
 */
$wnd.xh.xport = $entry(function(formatName, node, efParams) {
  var efs = $wnd.xh.service('ExternalFormatService');
  if (efs) {
    // IXholonService.SIG_PROCESS_REQUEST = -3998
    var data = formatName;
    if (efParams !== undefined) {
      data = [formatName, efParams];
    }
    efs.call(-3998, data, node);
  }
});

/**
 * Get an array of external format names.
 * @method xports
 * @return {Array} An array of strings. Example:
 *   Csv
 *   GraphML
 *   Graphviz
 *   MindMap
 *   Yaml
 *   _other,ChapNetwork,ChapTree,Newick
 *   _xholon,Cd,Csh,Ih,Xhn
 *   _d3,CirclePack
 * @example
 *     var root = $wnd.xh.root();
 *     var formatNamesArr = $wnd.xh.xports();
 *     for (var i = 0; i < formatNamesArr.length; i++) {
 *       root.println(formatNamesArr[i]);
 *     }
 */
$wnd.xh.xports = $entry(function() {
  var efs = $wnd.xh.service('ExternalFormatService');
  if (efs) {
    return efs.actions();
  }
  return "";
});

/**
 * Get or set the system Avatar.
 * Note: Avatar extends AbstractAvatar, which extends XholonWithPorts.
 * @method avatar
 * @param {Avatar} newAvatar Optional new system Avatar.
 * @return {Avatar} An IXholon (Avatar) node, or null.
 * @example
 *     const ava = $wnd.xh.avatar();
 *     ava.action("where;look");
 * @example
 *     $wnd.xh.avatar(newAvatar);
 */
$wnd.xh.avatar = $entry(function(newAvatar) {
  if (newAvatar === undefined) {
    return app.@org.primordion.xholon.app.Application::getAvatar()();
  }
  else {
    app.@org.primordion.xholon.app.Application::setAvatar(Lorg/primordion/xholon/base/IXholon;)(newAvatar);
  }
});

/**
 * Get or set the Avatar key map.
 * @method avatarKeyMap
 * @param {String} keyMap Optional new key map.
 * @return {String} Current key map, or null.
 * @example
 *     const akmStr = xh.avatarKeyMap();
 *     console.log(akmStr);
 * @example
 *     var json = xh.avatarKeyMap();
 *     var obj = JSON.parse(json);
 *     obj.X = "build Cat role Licorice";
 *     obj.Y = "build Dog role Fido";
 *     obj["1"] = "take *cat";
 *     var newJson = JSON.stringify(obj);
 *     $wnd.xh.avatarKeyMap(newJson);
 */
$wnd.xh.avatarKeyMap = $entry(function(keyMap) {
  if (keyMap === undefined) {
    return app.@org.primordion.xholon.app.Application::getAvatarKeyMap()();
  }
  else {
    app.@org.primordion.xholon.app.Application::setAvatarKeyMap(Ljava/lang/String;)(keyMap);
  }
});
    
/**
 * Set up speech recognition.
 * @method speechRecognition
 * @param {String} lang (ex: "en-GB")
 * @return 
 */
$wnd.xh.speechRecognition = $entry(function(lang) {})

/**
 * Enable external access through a new Avatar, using WebRTC PeerJS.
 * This would typically be used from PeerjsChat.html
 * @method webRTC
 * @param id {String} optional
 * @param key {String} peerjs demo API key, or other
 * @param {Number} debug debug level (0 - 3)
 * @return null
 * @example
 *     xh.webRTC();
 * @example
 *     xh.webRTC("Alligator", undefined, 3);
 */
$wnd.xh.webRTC = $entry(function(id, key, debug) {})

/**
 * Show contents of browser local storage.
 * It prints this to the Xholon GUI out tab.
 * @method showLocalStorage
 * @return null
 * @example
 *     var locstor = $wnd.xh.showLocalStorage();
 *     console.log(locstor);
 */
$wnd.xh.showLocalStorage = $entry(function() {})

/**
 * Determine if obj is an instance of a Java class that descends from Xholon.java.
 * @method isXholonNode
 * @param {Object} obj Any JS object.
 * @return {boolean} true or false
 * @example
 *     $wnd.xh.isXholonNode(xh.root());  //returns true
 *     $wnd.xh.isXholonNode(13);         //returns false
 */
$wnd.xh.isXholonNode = $entry(function(obj) {
  return @org.client.XholonJsApi::isXholonNode(Ljava/lang/Object;)(obj);
});

/**
 * Determine if obj is an instance of a Java class that descends from Xholon.java.
 * @method isXholonNodeCanonical
 * @param {Object} obj Any JS object.
 * @return {boolean} true or false
 * @example
 *     $wnd.xh.isXholonNodeCanonical(xh.root());  //returns true
 *     $wnd.xh.isXholonNodeCanonical(13);         //returns false
 */
$wnd.xh.isXholonNodeCanonical = $entry(function(obj) {
  return @org.client.XholonJsApi::isXholonNodeCanonical(Ljava/lang/Object;)(obj);
});

/**
 * replacement for Javascript Math.random(), with a seed
 * @method random
 * @return {Number} a random real number between 0 and 1
 * @example
 *     console.log($wnd.xh.random()); // 0.0138649232303234
 */
$wnd.xh.random = $entry(function() {
  return @org.primordion.xholon.util.MiscRandom::random()();
});

/**
 * Seed the random number generator
 * @method seed
 * @param {Number} An integer.
 * example
 *     $wnd.xh.seed(5297);
 */
$wnd.xh.seed = $entry(function(seed) {
  @org.primordion.xholon.util.MiscRandom::seedRandomNumberGeneratorInt(I)(seed);
});

/**
 * Match graph
 * @method matchGraph
 * @param {String} graphStr 
 * @param {String} subgraphStr 
 * @param {String} separator 
 * @return 
 * @example
 *     // TODO
 */
$wnd.xh.matchGraph = $entry(function(graphStr, subgraphStr, separator) {
  if (separator === undefined) {separator = "\n";}
  return @org.wip.VF2.runner.App::matchGraph(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)(graphStr, subgraphStr, separator);
});

/**
 * These methods apply to individual IXholon nodes in the Xholon application.
 * A Xholon is a node within a hierarchical tree structure, and builds on the capabilities of tree nodes.
 * A tree node is a node in a tree.
 * It has one parent (none if it's the root), and may have one or more children, and one or more siblings.
 * A Xholon is both a whole, and a part of some other Xholon, at the same time.
 * A Xholon is an instance of a IXholonClass.
 * A Xholon can be an active object, a passive object, a container, or any combination of these three,
 * as defined by its IXholonClass.
 *
 * @class ixholon
 * @constructor
 */
$wnd.xh.ixholonapi = new Object();

var api = $wnd.xh.ixholonapi;

/**
 * Get parent of this node.
 * @method parent
 * @return {IXholon} This node's current parent, or null if this is a root node.
 * @example
 *     var p = node.parent();
 */
api.parent = $entry(function() {
  return this.@org.primordion.xholon.base.IXholon::getParentNode()();
});

/**
 * Get first (leftmost) child of this node.
 * @method first
 * @return {IXholon} First child, or null.
 * @example
 *     var f = node.first();
 */
api.first = $entry(function() {
  return this.@org.primordion.xholon.base.IXholon::getFirstChild()();
});

/**
 * Get last (rightmost) child of this node.
 * @method last
 * @return {IXholon} Last child, or null.
 * @example
 *     var f = node.last();
 */
api.last = $entry(function() {
  return this.@org.primordion.xholon.base.IXholon::getLastChild()();
});

/**
 * Get next (right) sibling of this node.
 * @method next
 * @return {IXholon} Next sibling, or null.
 * @example
 *     var n = node.next();
 */
api.next = $entry(function() {
  return this.@org.primordion.xholon.base.IXholon::getNextSibling()();
});

/**
 * Get previous (left) sibling of this node. (may be expensive in processing time)
 * @method prev
 * @return {IXholon} Previous sibling, or null.
 * @example
 *     var p = node.prev();
 */
api.prev = $entry(function() {
  return this.@org.primordion.xholon.base.IXholon::getPreviousSibling()();
});

/**
 * Binary Tree parent.
 * @method btparent
 * @return {IXholon} a node
 * @example
 *     console.log(node.btparent());
 * @example
 *     console.log(temp0.btparent().name()); // eukaryoticCell_3
 */
api.btparent = $entry(function() {
  return this.@org.primordion.xholon.base.IXholon::getBinaryTreeParent()();
});

/**
 * Binary Tree left.
 * @method btleft
 * @return {IXholon} a node
 * @example
 *     console.log(node.btleft());
 * @example
 *     console.log(temp0.btleft().name()); // cellBilayer_5
 */
api.btleft = $entry(function() {
  return this.@org.primordion.xholon.base.IXholon::getBinaryTreeLeft()();
});

/**
 * Binary Tree right.
 * @method btright
 * @return {IXholon} a node
 * @example
 *     console.log(node.btright());
 * @example
 *     console.log(temp0.btright().name()); // cytoplasm_6
 */
api.btright = $entry(function() {
  return this.@org.primordion.xholon.base.IXholon::getBinaryTreeRight()();
});



/**
 * Detach this node from its parent and from any siblings.
 * Any siblings are reattached to each other.
 * If there was a previous sibling and a next sibling,
 * these will be attached to each other.
 * If there was only a previous sibling, it's next sibling will now be null.
 * If this node was the parent's firstChild,
 * the parent's firstChild link will be appropriately adjusted.
 * Any children are left intact. The entire subtree is detached.
 * @method remove
 * @chainable
 * @return {IXholon} this
 * @example
 *     node.remove().appendTo(target);
 */
api.remove = $entry(function() {
  this.@org.primordion.xholon.base.IXholon::removeChild()();
  return this;
});

/**
 * Append a node as the last child of this node.
 * @method append
 * @chainable
 * @param {IXholon|String} content An existing IXholon node,
 * or an XML String that defines a new node or subtree.
 * @return {IXholon} this
 * @example
 *     node.append(otherNode.remove());
 *     node.append('<One/>');
 *     node.append('<One><Two roleName="subtreeNode"/></One>');
 */
api.append = $entry(function(content) {
  if (content) {
    if (typeof content == "string") {
      $wnd.xh.service('XholonHelperService').call(-2013, content, this);
    }
    else {
      content.@org.primordion.xholon.base.IXholon::appendChild(Lorg/primordion/xholon/base/IXholon;)(this);
    }
  }
  return this;
});

/**
 * Append this node as the last child of its new parent node.
 * @method appendTo
 * @chainable
 * @param {IXholon} target New parent of this node.
 * @return {IXholon} this
 * @example
 *     node.remove().appendTo(target);
 */
api.appendTo = $entry(function(target) {
  this.@org.primordion.xholon.base.IXholon::appendChild(Lorg/primordion/xholon/base/IXholon;)(target);
  return this;
});

/**
 * Insert a node as the first child of this node.
 * @method prepend
 * @chainable
 * @param {IXholon|String} content An existing IXholon node,
 * or an XML String that defines a new node or subtree.
 * @return {IXholon} this
 * @example
 *     node.prepend(otherNode.remove());
 *     node.prepend('<One/>');
 *     node.prepend('<One><Two roleName="subtreeNode"/></One>');
 */
api.prepend = $entry(function(content) {
  if (content) {
    if (typeof content == "string") {
      $wnd.xh.service('XholonHelperService').call(-2014, content, this);
    }
    else {
      content.@org.primordion.xholon.base.IXholon::insertFirstChild(Lorg/primordion/xholon/base/IXholon;)(this);
    }
  }
  return this;
});

/**
 * Insert this node as the first child of its new parent node.
 * @method prependTo
 * @chainable
 * @param {IXholon} target New parent of this node.
 * @return {IXholon} this
 * @example
 *     node.remove().prependTo(target);
 */
api.prependTo = $entry(function(target) {
  this.@org.primordion.xholon.base.IXholon::insertFirstChild(Lorg/primordion/xholon/base/IXholon;)(target);
  return this;
});

/**
 * Insert a node before this node.
 * @method before
 * @chainable
 * @param {IXholon|String} content An existing IXholon node,
 * or an XML String that defines a new node or subtree.
 * @return {IXholon} this
 * @example
 *     node.before(otherNode.remove());
 *     node.before('<One/>');
 *     node.before('<One><Two roleName="subtreeNode"/></One>');
 */
api.before = $entry(function(content) {
  if (content) {
    if (typeof content == "string") {
      $wnd.xh.service('XholonHelperService').call(-2016, content, this);
    }
    else {
      content.@org.primordion.xholon.base.IXholon::insertBefore(Lorg/primordion/xholon/base/IXholon;)(this);
    }
  }
  return this;
});

/**
 * Insert this node before its new next sibling node.
 * @method insertBefore
 * @chainable
 * @param {IXholon} target New next sibling of this node.
 * @return {IXholon} this
 * @example
 *     node.insertBefore(target);
 */
api.insertBefore = $entry(function(target) {
  this.@org.primordion.xholon.base.IXholon::insertBefore(Lorg/primordion/xholon/base/IXholon;)(target);
  return this;
});

/**
 * Insert a node after this node.
 * @method after
 * @chainable
 * @param {IXholon|String} content An existing IXholon node,
 * or an XML String that defines a new node or subtree.
 * @return {IXholon} this
 * @example
 *     node.after(otherNode.remove());
 *     node.after('<One/>');
 *     node.after('<One><Two roleName="subtreeNode"/></One>');
 */
api.after = $entry(function(content) {
  if (content) {
    if (typeof content == "string") {
      $wnd.xh.service('XholonHelperService').call(-2015, content, this);
    }
    else {
      content.@org.primordion.xholon.base.IXholon::insertAfter(Lorg/primordion/xholon/base/IXholon;)(this);
    }
  }
  return this;
});

/**
 * Insert this node after its new previous sibling node.
 * @method insertAfter
 * @chainable
 * @param {IXholon} target New previous sibling of this node.
 * @return {IXholon} this
 * @example
 *     node.insertAfter(target);
 */
api.insertAfter = $entry(function(target) {
  this.@org.primordion.xholon.base.IXholon::insertAfter(Lorg/primordion/xholon/base/IXholon;)(target);
  return this;
});

/**
 * Clone current node including its entire subtree, as this current node's new last child.
 * @method cloneLastChild
 * @chainable
 * @return the current node
 * @example
 *     console.log(node.cloneLastChild().last().name()); // 
 */
api.cloneLastChild = $entry(function() {
  $wnd.xh.service('XholonHelperService').call(-2024, this, this); // cellMembrane_97
  return this;
});

/**
 * Clone first child.
 * @method cloneFirstChild
 */
api.cloneFirstChild = $entry(function() {
  $wnd.xh.service('XholonHelperService').call(-2025, this, this);
  return this;
});

/**
 * Clone after.
 * @method cloneAfter
 */
api.cloneAfter = $entry(function() {
  $wnd.xh.service('XholonHelperService').call(-2026, this, this);
  return this;
});

/**
 * Clone before.
 * @method cloneBefore
 */
api.cloneBefore = $entry(function() {
  $wnd.xh.service('XholonHelperService').call(-2027, this, this);
  return this;
});


/**
 * Get ID of this IXholon instance.
 * @method id
 * @return {Number} An integer ID, unique within this application, that is assigned when the IXholon is created.
 * @example
 *     var id = node.id();
 *     console.log("The id for node " + node.toString() + " is " + id);
 */
api.id = $entry(function() {
  return this.@org.primordion.xholon.base.IXholon::getId()();
});

/**
 * _id  (in general, this is for system use only)
 * @method _id
 * @param {Number} an integer or no param
 * @return the node's current id, or the node itself
 */
api._id = $entry(function(iid) {
  if (iid === undefined) {
    return this.@org.primordion.xholon.base.IXholon::getId()();
  }
  else {
    this.@org.primordion.xholon.base.IXholon::setId(I)(iid);
    return this;
  }
});

/**
 * identity
 * @method identity
 * @return the node's identity (typically just the id)
 */
api.identity = $entry(function() {
  return this.@org.primordion.xholon.base.IXholon::getIdentity()();
});

/**
 * Get name, unique within this application, of this Xholon instance.
 * The name is a concatenation of the IXholonClass name and the Xholon unique ID.
 * The first letter is converted to lowercase, and a "_" is used to separate
 * the name and ID (ex: "helloWorld_123").
 * If the Xholon instance has a roleName,
 * it is included in front of the other two elements,
 * and separated from the IXholonClass name by a ":" (ex: "helloRole:helloWorld_123").
 * @method name
 * @param [template="r:c_i^"] {String} A fixed length template that specifies what elements are included
 * as part of the name.
 * ex: "r:c_i^" is roleName + ":" + className with first letter lowercase + "_" + id
 * The template fields are in fixed positions, and may have the following values:
 * (1) r include roleName, ^ don't include role name
 * (2) : ^
 * (3) c className lowercase, C classname lowercase, l local part, L local part
 * (4) _ ^
 * (5) i include id
 * (6) ^
 * If an invalid template is input, then the returned name will be in the default format,
 * as defined by the GETNAME_DEFAULT constant.
 * The default format is exactly the same as what would be returned by calling getName()
 * without specifying a template.
 * @return {String} The default or formatted name of this IXholon instance.
 * @example
 *     var name = node.name();
 *     console.log(name);
 *     name = node.name("R^^^^^");
 *     console.log(name);
 */
api.name = $entry(function(template) {
  if (!template) {
    return this.@org.primordion.xholon.base.IXholon::getName()();
  }
  else {
    return this.@org.primordion.xholon.base.IXholon::getName(Ljava/lang/String;)(template);
  }
});

/**
 * Get or set the name of the role played by this Xholon within a specific context.
 * @method role
 * @chainable
 * @param {String} [roleName] An optional string that identifies the role.
 * @return {String} A name that identifies the role, or null.
 * @example
 *     console.log(node.role());
 *     node.role("myNewRole");
 *     console.log(node.role());
 */
api.role = $entry(function(roleName) {
  if (roleName === undefined) {
    return this.@org.primordion.xholon.base.IXholon::getRoleName()();
  }
  else {
    this.@org.primordion.xholon.base.IXholon::setRoleName(Ljava/lang/String;)(roleName);
    return this;
  }
});

/**
 * Get the node's xh type (1 2 3 4).
 * @method xhType
 * @return {Number} 1, 2, 3, or 4.
 */
api.xhType = $entry(function() {
  return this.@org.primordion.xholon.base.IXholon::getXhType()();
});

/**
 * Write an object to the out tab.
 * @method print
 * @chainable
 * @param {Object} obj The object to write. Currently, this must be a String.
 * @return {IXholon} this
 * @example
 *     node.print("Hello ");
 */
api.print = $entry(function(obj) {
  this.@org.primordion.xholon.base.IXholon::print(Ljava/lang/Object;)(obj);
  return this;
});

/**
 * Write an object to the out tab, terminated with an end-of-line.
 * @method println
 * @chainable
 * @param {Object} obj The object to write. Currently, this must be a String.
 * @return {IXholon} this
 * @example
 *     node.println("World");
 */
api.println = $entry(function(obj) {
  this.@org.primordion.xholon.base.IXholon::println(Ljava/lang/Object;)(obj);
  return this;
});

/**
 * Get the IXholonClass to which this Xholon instance is a member.
 * @method xhc
 * @return {IXholonClass} The IXholonClass, which is a subclass of IXholon.
 * @example
 *     var xhc = node.xhc();
 *     console.log(xhc.name());
 */
api.xhc = $entry(function() {
  return this.@org.primordion.xholon.base.IXholon::getXhc()();
});

/**
 * Get or set the contents of the annotation for this Xholon.
 * The annotation is intended to be read by a human user.
 * @method anno
 * @chainable
 * @param {String} [annotation] Some text.
 * @return {String} Some text, or null.
 * Or {IXholon} this
 * @example
 *     console.log(node.anno());
 *     node.anno("Here is my new description of the current node.");
 *     console.log(node.anno());
 */
api.anno = $entry(function(annotation) {
  if (annotation === undefined) {
    return this.@org.primordion.xholon.base.IXholon::getAnnotation()();
  }
  else {
    this.@org.primordion.xholon.base.IXholon::setAnnotation(Ljava/lang/String;)(annotation);
    return this;
  }
});

/**
 * Get or set a numeric value maintained by this xholon instance.
 * If a class that implements this interface does not maintain a numeric value, it should return 0.0 
 * @method val
 * @chainable
 * @param {Number} [val] A number.
 * @return {Number} A number.
 * Or {IXholon} this
 * @example
 *     console.log(node.val());
 *     node.val(1234.5678);
 *     console.log(node.val());
 */
api.val = $entry(function(val) {
  if (val === undefined) {
    return this.@org.primordion.xholon.base.IXholon::getVal()();
  }
  else {
    this.@org.primordion.xholon.base.IXholon::setVal(D)(val);
    return this;
  }
});

/**
 * Increment an internal number by a specified amount. This is a convenience method.
 * @method inc
 * @chainable
 * @param {Number} incAmount Increment amount.
 * @return {IXholon} this
 * @example
 *     console.log(node.val());
 *     node.val(1234.5678);
 *     console.log(node.val());
 *     node.inc(1111.1111);
 *     console.log(node.val());
 */
api.inc = $entry(function(incAmount) {
  this.@org.primordion.xholon.base.IXholon::incVal(D)(incAmount);
  return this;
});

/**
 * Decrement an internal number by a specified amount. This is a convenience method.
 * @method dec
 * @chainable
 * @param {Number} decAmount Decrement amount.
 * @return {IXholon} this
 * @example
 *     console.log(node.val());
 *     node.val(1234.5678);
 *     console.log(node.val());
 *     node.dec(1111.1111);
 *     console.log(node.val());
 */
api.dec = $entry(function(decAmount) {
  this.@org.primordion.xholon.base.IXholon::decVal(D)(decAmount);
  return this;
});

/**
 * Get or set the value of a String maintained by this xholon instance.
 * The text is intended to be read and processed by the application,
 * for its own internal purposes.
 * @method text
 * @chainable
 * @param {String} [val] Some text.
 * @return {String} Some text, or null.
 * Or {IXholon} this
 * @example
 *     console.log(node.text());
 *     node.val("one,two.three");
 *     console.log(node.text());
 */
api.text = $entry(function(val) {
  if (val === undefined) {
    return this.@org.primordion.xholon.base.IXholon::getVal_String()();
  }
  else {
    this.@org.primordion.xholon.base.IXholon::setVal_String(Ljava/lang/String;)(val);
    return this;
  }
});

/**
 * Get or set the value of a boolean maintained by this xholon instance.
 * @method bool
 * @chainable
 * @param {boolean} [val] Some text.
 * @return {boolean} Some text, or null.
 * Or {IXholon} this
 * @example
 *     console.log(node.bool());
 *     node.bool(true);
 *     console.log(node.bool());
 */
api.bool = $entry(function(val) {
  if (val === undefined) {
    return this.@org.primordion.xholon.base.IXholon::getVal_boolean()();
  }
  else {
    this.@org.primordion.xholon.base.IXholon::setVal_boolean(Z)(val);
    return this;
  }
});

/**
 * Get or set the value of a Object maintained by this xholon instance.
 * @method obj
 * @chainable
 * @param {Object} [val] An object.
 * @return {Object} An object.
 * Or {IXholon} this
 * @example
 *     var obj = node.obj();
 */
api.obj = $entry(function(val) {
  if (val === undefined) {
    return this.@org.primordion.xholon.base.IXholon::getVal_Object()();
  }
  else {
    this.@org.primordion.xholon.base.IXholon::setVal_Object(Ljava/lang/Object;)(val);
    return this;
  }
});

/**
 * Send a message to a receiving IXholon instance.
 * @method msg
 * @chainable
 * @param {Number} signal A distinguishing identifier for this message.
 * @param {Object} data Any data that needs to be sent, or null.
 * @param {IXholon} sender The sender of the message.
 * @param {Number} [index] The index of a replicated port.
 * @return {IXholon} this
 * @example
 *     receiverNode.msg(101, "This is some data", thisNode);
 */
api.msg = $entry(function(signal, data, sender, index) {
  if (index === undefined) {
    this.@org.primordion.xholon.base.IXholon::sendMessage(ILjava/lang/Object;Lorg/primordion/xholon/base/IXholon;)(signal, data, sender);
    return this;
  }
  else {
    this.@org.primordion.xholon.base.IXholon::sendMessage(ILjava/lang/Object;Lorg/primordion/xholon/base/IXholon;I)(signal, data, sender, index);
    return this;
  }
});

/**
 * Send a Synchronous message to a receiving IXholon instance.
 * @method call
 * @param {Number} signal A distinguishing identifier for this message.
 * @param {Object} data Any data that needs to be sent, or null.
 * @param {IXholon} sender The sender of the message.
 * @param {Number} [index] The index of a replicated port.
 * @return {Object} A response message, or null.
 * @example
 *     var responseMsg = receiverNode.call(102, "What is 2 + 3 ?", thisNode);
 *     console.log(responseMsg.data);
 */
api.call = $entry(function(signal, data, sender, index) {
  var responseMsg = null;
  if (index === undefined) {
    responseMsg = this.@org.primordion.xholon.base.IXholon::sendSyncMessage(ILjava/lang/Object;Lorg/primordion/xholon/base/IXholon;)(signal, data, sender);
  }
  else {
    responseMsg = this.@org.primordion.xholon.base.IXholon::sendSyncMessage(ILjava/lang/Object;Lorg/primordion/xholon/base/IXholon;I)(signal, data, sender, index);
  }
  if (responseMsg) {
    return responseMsg.obj();
  }
  else {
   return null;
  }
});

/**
 * Get a list of actions that this xholon can do.
 * These actions can be presented to users in a GUI, or used for other purposes.
 * @method actions
 * @return {String[]} A list of actions, or null.
 * @example
 *     console.log(node.actions());
 */
api.actions = $entry(function() {
  return this.@org.primordion.xholon.base.IXholon::getActionList()();
});

/**
 * Do a specific action that this xholon knows how to do.
 * @method action
 * @chainable
 * @param {String} action The name of a specific action.
 * @return {IXholon} this
 * @example
 *     node.action("Do your thing");
 */
api.action = $entry(function(action) {
  this.@org.primordion.xholon.base.IXholon::doAction(Ljava/lang/String;)(action);
  return this;
});

/**
 * Interact with a node every time step.
 * @method tick
 * @param {Object} a JS Object for the node to process
 * @return {Object}
 */
api.tick = $entry(function(objekt) {
  if (objekt === undefined) {
    var objekt = null;
  }
  return this.@org.primordion.xholon.base.IXholon::tick(Ljava/lang/Object;)(objekt);
});

/**
 * Process a visit, and return a result (true or false). ???
 * @method visit
 * @param visitee
 * @return 
 * @example
 *     // TODO
 */
api.visit = $entry(function(visitee) {
  return this.@org.primordion.xholon.base.IXholon::visit(Lorg/primordion/xholon/base/IXholon;)(visitee);
});

/**
 * Get or set the node referenced by a port with a specified name or index (0-based).
 * @method port
 * @chainable
 * @param {String|Number} portName The name of the port,
 * or the index of the port within this Xholon's port array.
 * @param {IXholon} [portRef] The IXholon instance that can be accessed through this port.
 * @return {IXholon} A reference to an IXholon instance that can be accessed through this port,
 * or null, or this.
 * @example
 *     console.log(node.port("world"));
 *     console.log(node.port(1));
 * @example
 *     node
 *       .port(0, nodeA)
 *       .port(1, nodeB)
 *       .port("world", nodeC);
 */
api.port = $entry(function(portName, portRef) {
  if (portRef === undefined) {
    if (isNaN(portName)) {
      // portName is a String
      var node = this;
      var clazz = node.@org.primordion.xholon.base.IXholon::getClass()();
      var app = $wnd.xh.app();
      return app.@org.primordion.xholon.app.Application::getAppSpecificObjectVal(Lorg/primordion/xholon/base/IXholon;Ljava/lang/Class;Ljava/lang/String;)(node, clazz, portName);
    }
    else {
      // portName is a number
      return this.@org.primordion.xholon.base.IXholon::getPort(I)(portName);
    }
  }
  else {
    if (isNaN(portName)) {
      // portName is a String
      // public boolean setAppSpecificObjectVal(IXholon tNode, String attrName, IXholon val)
      var node = this;
      var clazz = node.@org.primordion.xholon.base.IXholon::getClass()();
      var app = $wnd.xh.app();
      app.@org.primordion.xholon.app.Application::setAppSpecificObjectVal(Lorg/primordion/xholon/base/IXholon;Ljava/lang/Class;Ljava/lang/String;Lorg/primordion/xholon/base/IXholon;)(node, clazz, portName, portRef);
      return this;
    }
    else {
      // portName is a number
      this.@org.primordion.xholon.base.IXholon::setPort(ILorg/primordion/xholon/base/IXholon;)(portName, portRef);
      return this;
    }
  }
});

/**
 * Get all ports as an array.
 * @method ports
 * @return {PortInformation[]} An array of PortInformation objects, or an empty array.
 * @example
 *     console.log(node.ports()[0].obj().reffedNode.toString());
 */
api.ports = $entry(function() {
  return @org.client.XholonJsApi::ports(Lorg/primordion/xholon/base/IXholon;)(this);
});

/**
 * Get all ports as an array.
 * @method portSpec
 * @return {PortInformation[]} An array of PortInformation objects, or an empty array.
 * @example
 *     console.log(node.portSpec()[0].obj().reffedNode.toString());
 */
api.portSpec = $entry(function() {
  return @org.client.XholonJsApi::portSpec(Lorg/primordion/xholon/base/IXholon;)(this);
});

/**
 * Get the names of all ports.
 * @method portNames
 * @return {String} A comma-separated list of port names and indexes.
 * @example
 *     console.log(node.portNames());
 */
api.portNames = $entry(function() {
  var node = this;
  var clazz = node.@org.primordion.xholon.base.IXholon::getClass()();
  var app = $wnd.xh.app();
  return app.@org.primordion.xholon.app.Application::getAppSpecificObjectValNames(Lorg/primordion/xholon/base/IXholon;Ljava/lang/Class;)(node, clazz);
});

/**
 * Use JavaScript to return an array of all links/references from this node to other Xholon nodes.
 * @method links
 * @param {boolean} placeGraph Whether or not to include place-graph links (parent, first, next, xhc, app)
 * @param {boolean} linkGraph Whether or not to include link-graph links (ports, etc.)
 * @return An array of objects. This is the same format as calling: node.ports()[0].obj();
 */
api.links = $entry(function(placeGraph, linkGraph) {})

/**
 * Return a collection of neighbors.
 * @method neighbors
 * @return 
 */
api.neighbors = $entry(function(placeGraph, linkGraph) {})

/**
 * Get or set the value of an attribute.
 * setter ex: root.attr("State", "9");
 * setter ex: root.attr("State", 17);
 * getter ex: Number(root.attr("state")) + 11;
 * @method attr
 * @chainable
 * @param {String} attrName An attribute name.
 * @param {String} [attrVal] An attribute value.
 * @return {String|IXholon} An attribute value, or null, or this.
 * @example
 *     console.log(node.attr("myAttr"));
 *     node.attr("myAttr", "myAttrVal");
 *     console.log(node.attr("myAttr"));
 */
api.attr = $entry(function(attrName, attrVal) {
  var node = this;
  var clazz = node.@org.primordion.xholon.base.IXholon::getClass()();
  var app = $wnd.xh.app();
  if (attrVal === undefined) {
    return app.@org.primordion.xholon.app.Application::getAppSpecificAttribute(Lorg/primordion/xholon/base/IXholon;Ljava/lang/Class;Ljava/lang/String;)(node, clazz, attrName);
  }
  else {
    app.@org.primordion.xholon.app.Application::setAppSpecificAttribute(Lorg/primordion/xholon/base/IXholon;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)(node, clazz, attrName, attrVal.toString());
    return this;
  }
});

/**
 * Is there an attribute with the specified name.
 * @method isAttr
 * @param {String} attrName An attribute name.
 * @return {boolean} true or false
 * @example
 *     console.log(node.isAttr("myAttr"));
 */
api.isAttr = $entry(function(attrName) {
  var node = this;
  var clazz = node.@org.primordion.xholon.base.IXholon::getClass()();
  var app = $wnd.xh.app();
  return app.@org.primordion.xholon.app.Application::isAppSpecificAttribute(Lorg/primordion/xholon/base/IXholon;Ljava/lang/Class;Ljava/lang/String;)(node, clazz, attrName);
});

/**
 * Get all app-specific attributes.
 * @method attrs
 * @param {boolean} returnAll Whether to return just the app-specific attributes (false),
 * or also the attributes of base superclasses (true).
 * @return {Object[][]} 
 * @example
 *     console.log(node.attrs(false));
 */
api.attrs = $entry(function(returnAll) {
  var node = this;
  var clazz = node.@org.primordion.xholon.base.IXholon::getClass()();
  var app = $wnd.xh.app();
  return app.@org.primordion.xholon.app.Application::getAppSpecificAttributes(Lorg/primordion/xholon/base/IXholon;Ljava/lang/Class;Z)(node, clazz, returnAll);
});

/**
 * Get attributes.
 * usage: xh.root().attrz(false, true, false, true);
 * example of returned Object: {first_: "Bob", last_: "Bo"}
 * @method attrz
 * @param {boolean} javaAttrs
 * @param {boolean} jsAttrs
 * @param {boolean} returnAll
 * @param {boolean} noDollar
 */
api.attrz = $entry(function(javaAttrs, jsAttrs, returnAll, noDollar) {})

/**
 * Evaluate an XPath 1.0 expression.
 * @method xpath
 * @param {String} expression An XPath 1.0 String expression (ex: "ancestor::HelloWorldSystem/World");
 * @return {IXholon} An IXholon node, or null.
 * @example
 *     var hello = $wnd.xh.root().first();
 *     var world = hello.xpath("ancestor::HelloWorldSystem/World");
 */
api.xpath = $entry(function(expression) {
  return @org.client.XholonJsApi::xpath(Ljava/lang/String;Lorg/primordion/xholon/base/IXholon;)(expression, this);
});

/**
 * Report whether or not this node has the specified Xholon class.
 * @method hasClass
 * @param {String} className The name of a XholonClass (xhc).
 * @return {boolean} true if the node's XholonClass (xhc) matches the className,
 *   or if any ancestor (superclass) of the xhc matches.
 * @example
 *     var x = $wnd.xh.root().first().hasClass("Hello");
 */
api.hasClass = $entry(function(className) {});

/**
 * Search XholonClass hierarchy (this.xhc() and this.xhc() ancestors) for a named attribute
 * getter and setter
 * @method classAttr
 * @param attrName {String} 
 * @param attrVal {Object}
 * @return {Object} an attribute value or null
 */
api.classAttr = $entry(function(attrName, attrVal) {
  var xhc = this.xhc();
  while (xhc) {
    if (xhc[attrName]) {
      if (attrVal === undefined) {
        return xhc[attrName];
      }
      else {
        xhc[attrName] = attrVal;
      }
    }
    xhc = xhc.parent();
  }
});

/**
 * @method hashify
 * @param {String} type
 * @return {String} ???
 * @example
 *    hashify("newick")
 *    hashify("sxpres")
 *    hashify("parenth")
 */
api.hashify = $entry(function(type) {
  if (type === undefined) {
    return this.@org.primordion.xholon.base.IXholon::hashify(Ljava/lang/String;)(null);
  }
  else {
    return this.@org.primordion.xholon.base.IXholon::hashify(Ljava/lang/String;)(type);
  }
});

/**
 * Open a XholonConsole on a node.
 * @method xhconsole
 * @return {IXholon} an instance of XholonConsole, or null.
 * @example
 *     var cons = $wnd.xh.root().xhconsole();
 */
api.xhconsole = $entry(function() {
  var msg = $wnd.xh.service('XholonHelperService').call(-2011, this, null);
  if (msg) {
    return msg.data[1];
  }
  else {
    return null;
  }
});

/**
 * select
 * @method select
 * @return 
 */
api.select = $entry(function() {
  var app = $wnd.xh.app();
  return app.@org.primordion.xholon.app.Application::handleNodeSelection(Lorg/primordion/xholon/base/IXholon;Ljava/lang/String;)(this, this.name());
});

/**
 * subtreez
 * function name uses "z" instead of "s", so it doesn't conflict with the "subtrees" attribute
 * @method subtreez
 * @param {String} stNames
 * @return 
 */
api.subtreez = $entry(function(stNames) {
  if (stNames === undefined) {
    return this.@org.primordion.xholon.base.IXholon::subtrees(Ljava/lang/String;)(null);
  }
  else {
    return this.@org.primordion.xholon.base.IXholon::subtrees(Ljava/lang/String;)(stNames);
  }
});

/**
 * subtree
 * @method subtree
 * @param {String} stName
 * @return 
 */
api.subtree = $entry(function(stName) {
  if (stName === undefined) {
    return this.@org.primordion.xholon.base.IXholon::subtree(Ljava/lang/String;)(null);
  }
  else {
    return this.@org.primordion.xholon.base.IXholon::subtree(Ljava/lang/String;)(stName);
  }
});

// uid
// Xholon native functions use this["uuid"], so there will be no conflict between the function name ("uid") and the property name "uuid"
/**
 * uid
 * @method uid
 * @param {String} uidArg
 * @return {String} uid or {IXholon} this
 */
api.uid = $entry(function(uidArg) {
  if (uidArg === undefined) {
    return this.@org.primordion.xholon.base.IXholon::getUid()();
  }
  else {
    this.@org.primordion.xholon.base.IXholon::setUid(Ljava/lang/String;)(uidArg);
    return this;
  }
});

// IDecoration methods

// var color = node.color();
// var color = node.xhc().color();
// node.color("0x00ff00"); node.color("#ff0000");
// node.xhc().color("rgba(0,255,0,0.5)");
/**
 * color
 * @method color
 * @param {String} val
 * @return {String} color or {IXholon} this
 * @example
 *     var color = node.color();
 *     var color = node.xhc().color();
 *     node.color("0x00ff00"); node.color("#ff0000");
 *     node.xhc().color("rgba(0,255,0,0.5)");
 */
api.color = $entry(function(val) {
  if (val === undefined) {
    return this.@org.primordion.xholon.base.IDecoration::getColor()();
  }
  else {
    this.@org.primordion.xholon.base.IDecoration::setColor(Ljava/lang/String;)(val);
    return this;
  }
});

/**
 * opacity
 * @method opacity
 * @param {String} val
 * @return {String} opacity or {IXholon} this
 */
api.opacity = $entry(function(val) {
  if (val === undefined) {
    return this.@org.primordion.xholon.base.IDecoration::getOpacity()();
  }
  else {
    this.@org.primordion.xholon.base.IDecoration::setOpacity(Ljava/lang/String;)(val);
    return this;
  }
});

/**
 * font
 * @method font
 * @param {String} val
 * @return {String} font or {IXholon} this
 */
api.font = $entry(function(val) {
  if (val === undefined) {
    return this.@org.primordion.xholon.base.IDecoration::getFont()();
  }
  else {
    this.@org.primordion.xholon.base.IDecoration::setFont(Ljava/lang/String;)(val);
    return this;
  }
});

/**
 * icon
 * @method icon
 * @param {String} val
 * @return {String} icon or {IXholon} this
 * @example
 *     me.icon("https://github.com/favicon.ico");
 */
api.icon = $entry(function(val) {
  if (val === undefined) {
    return this.@org.primordion.xholon.base.IDecoration::getIcon()();
  }
  else {
    this.@org.primordion.xholon.base.IDecoration::setIcon(Ljava/lang/String;)(val);
    return this;
  }
});

/**
 * toolTip
 * @method toolTip
 * @param {String} val
 * @return {String} toolTip or {IXholon} this
 */
api.toolTip = $entry(function(val) {
  if (val === undefined) {
    return this.@org.primordion.xholon.base.IDecoration::getToolTip()();
  }
  else {
    this.@org.primordion.xholon.base.IDecoration::setToolTip(Ljava/lang/String;)(val);
    return this;
  }
});

/**
 * symbol
 * @method symbol
 * @param {String} val
 * @return {String} symbol or {IXholon} this
 */
api.symbol = $entry(function(val) {
  if (val === undefined) {
    return this.@org.primordion.xholon.base.IDecoration::getSymbol()();
  }
  else {
    this.@org.primordion.xholon.base.IDecoration::setSymbol(Ljava/lang/String;)(val);
    return this;
  }
});

/**
 * format
 * @method format
 * @param {String} val
 * @return {String} format or {IXholon} this
 */
api.format = $entry(function(val) {
  if (val === undefined) {
    return this.@org.primordion.xholon.base.IDecoration::getFormat()();
  }
  else {
    this.@org.primordion.xholon.base.IDecoration::setFormat(Ljava/lang/String;)(val);
    return this;
  }
});

/**
 * geo
 * @method geo
 * @param {String} val
 * @return {String} geo or {IXholon} this
 */
api.geo = $entry(function(val) {
  if (val === undefined) {
    return this.@org.primordion.xholon.base.IDecoration::getGeo()();
  }
  else {
    this.@org.primordion.xholon.base.IDecoration::setGeo(Ljava/lang/String;)(val);
    return this;
  }
});

/**
 * sound
 * @method sound
 * @param {String} val
 * @return {String} sound or {IXholon} this
 */
api.sound = $entry(function(val) {
  if (val === undefined) {
    return this.@org.primordion.xholon.base.IDecoration::getSound()();
  }
  else {
    this.@org.primordion.xholon.base.IDecoration::setSound(Ljava/lang/String;)(val);
    return this;
  }
});

/**
 * childrenAsCsv
 * @method childrenAsCsv
 * @param {String} nameTemplate
 * @param {String} separator
 * @return {String} csv
 * @example
 *     var root = xh.root();
 *     console.log(root.first().childrenAsCsv());
 *     console.log(root.first().childrenAsCsv("R^^^^^","|"));
 *     console.log(root.first().childrenAsCsv("R^^^^^").split(","));
 *     console.log(root.first().childrenAsCsv("R^^^^^").split(",").sort());
 */
api.childrenAsCsv = $entry(function(nameTemplate, separator) {
  if (nameTemplate === undefined) {nameTemplate = null;}
  if (separator === undefined) {separator = null;}
  return this.@org.primordion.xholon.base.IXholon::getChildrenAsCsv(Ljava/lang/String;Ljava/lang/String;)(nameTemplate, separator);
});

/**
 * siblingsAsCsv
 * @method siblingsAsCsv
 * @param {String} nameTemplate
 * @param {String} separator
 * @return {String} csv
 * @example
 *     $wnd.xh.root().first().first().next().siblingsAsCsv("R^^^^^","|").split("|").sort();
 */
api.siblingsAsCsv = $entry(function(nameTemplate, separator) {
  if (nameTemplate === undefined) {nameTemplate = null;}
  if (separator === undefined) {separator = null;}
  return this.@org.primordion.xholon.base.IXholon::getSiblingsAsCsv(Ljava/lang/String;Ljava/lang/String;)(nameTemplate, separator);
});

/**
 * includes
 * @method includes
 * @param {String} targetStr
 * @param {String} nameTemplate
 * @param {String} separator
 * @return {boolean} true or false
 * @example
 *     var bool = node.includes("one,two", "R^^^^^", ",");
 *     var bool = root.first().includes("one,three,two", "R^^^^^", ","); bool // true
 *     var bool = root.first().includes("example,example,example", "^^c^^^", ","); bool // true
 */
api.includes = $entry(function(targetStr, nameTemplate, separator) {})

/**
 * arrayify
 * @method arrayify
 * @return {IXholon} this
 * @example
 *     console.log($wnd.xh.root().first().first().next().arrayify());
 */
api.arrayify = $entry(function() {
  var ix = 0;
  var node = this.first();
  while (node) {
    this[ix++] = node;
    node = node.next();
  }
  this.length = ix;
  return this;
});

/**
 * unarrayify - reverse the effect of arrayify()
 * @method unarrayify
 * @return {IXholon} this
 * @example
 *     console.log($wnd.xh.root().first().first().next().unarrayify());
 */
api.unarrayify = $entry(function() {
  var ix = 0;
  var node = this.first();
  while (node) {
    delete this[ix++];
    node = node.next();
  }
  delete this.length;
  return this;
});

/**
 * childrenAsArray
 * @method childrenAsArray
 * @return {Array}
 * @example
 *     var childarr = xh.root().childrenAsArray();
 */
api.childrenAsArray = $entry(function() {
  if (this.length) {
    return Array.prototype.slice.call(this);
  }
  else {
    var arr = [];
    var node = this.first();
    while (node) {
      arr.push(node);
      node = node.next();
    }
    return arr;
  }
});

/**
 * subtreeAsArray
 * @method subtreeAsArray
 * @return {Array}
 * @example
 *     var childarr = xh.root().subtreeAsArray();
 */
api.subtreeAsArray = $entry(function() {
  var starr = [];
  var recurse = function(pnode) {
    starr.push(pnode);
    var node = pnode.first();
    while (node) {
      recurse(node);
      node = node.next();
    }
  }
  recurse(this);
  return starr;
});

/**
 * cache - move children to an array
 * 2 possibilities:
 *  (1) move children to this.arrayify()
 *  (2) move children to a new array called ccache
 * TODO Avatar can crash the page if it tries to exit from a cache; it retains its contextNode
 * @method cache
 * @param {IXholon} destination
 * @return {IXholon} this
 * @example
 *     var childarr = xh.root().cache();
 */
api.cache = $entry(function(destination) {
  if (destination === undefined) {destination = "arrayify";} // "arrayify" or "ccache"
  switch (destination) {
  case "ccache":
    this.ccache = this.childrenAsArray();
    this.ccache.map(function(node) {node.remove();});
    break;
  case "arrayify":
  default:
    if (!this.length) {
      this.arrayify();
    }
    for (var i = 0; i < this.length; i++) {
      this[i].remove();
    }
    break;
  }
  return this;
});

/**
 * uncache - reverse the effects of cache()
 * @method uncache
 * @param {String} source "ccache" or "arrayify"
 * @return {IXholon} this
 */
api.uncache = $entry(function(source) {
  if (source === undefined) {source = "arrayify";} // "arrayify" or "ccache"
  switch (source) {
  case "ccache":
    if (this.ccache && this.ccache.length) {
      var len = this.ccache.length;
      for (var i = 0; i < len; i++) {
        this.append(this.ccache.shift());
      }
      delete this.ccache;
    }
    break;
  case "arrayify":
  default:
    if (this.length) {
      for (var i = 0; i < this.length; i++) {
        this.append(this[i]);
        delete this[i];
      }
      delete this.length;
    }
    break;
  }
  return this;
});

/**
 * Get Java class name, and optionally all Java superclass names
 * @method javaClassnames
 * @param {boolean} superclasses true or false  whether or not to include superclass names
 * @return {String} comma-separated string ex:  
 * "org.primordion.user.app.helloworldjnlp.XhHelloWorld,org.primordion.xholon.base.XholonWithPorts,org.primordion.xholon.base.Xholon,java.lang.Object"
 * @example
 *     $wnd.xh.app().javaClassnames(true).split(",").reverse();
 */
api.javaClassnames  = $entry(function(superclasses) {
  if (superclasses === undefined) {superclasses = false;}
  var clazz = this.@org.primordion.xholon.base.IXholon::getClass()();
  var str = clazz.@java.lang.Class::getName()();
  if (superclasses) {
    while (clazz) {
      clazz = clazz.@java.lang.Class::getSuperclass()();
      if (clazz) {
        str += "," + clazz.@java.lang.Class::getName()();
      }
    }
  }
  return str;
});

/**
 * Get size of complete subtree including this node.
 * @method treeSize
 * @param {boolean} deep
 * @return {Number}
 */
api.treeSize = $entry(function() {
  return this.@org.primordion.xholon.base.IXholon::treeSize()();
});

/**
 * Get number of immediate children.
 * @method numChildren
 * @param {boolean} deep
 * @return 
 */
api.numChildren = $entry(function(deep) {
  if (deep === undefined) {deep = false;}
  else {
    if ((deep == true) || (deep == "true")) {deep = true;}
    else {deep = false;}
  }
  return this.@org.primordion.xholon.base.IXholon::getNumChildren(Z)(deep);
});

/**
 * Get this node's numbering.
 * @method numbering
 * @return 
 */
api.numbering = $entry(function() {
  return this.@org.primordion.xholon.base.IXholon::getNumbering()();
});