/* Methods and properties added to facilitate creation of external linked tools.
 * This assumes that WeavePath.js has already been loaded. */
/* "use strict"; */

weave.WeavePath.prototype.probe_keyset = weave.path("defaultProbeKeySet");
weave.WeavePath.prototype.selection_keyset = weave.path("defaultSelectionKeySet");
weave.WeavePath.prototype.subset_filter = weave.path("defaultSubsetKeyFilter");

weave.WeavePath.prototype.qkeyToString = function(key)
{
    return JSON.stringify([key.keyType, key.localName]);
};
weave.WeavePath.prototype.stringToQKey = function(s) 
{
    var arr;
    var newQKey = {};

    try {
        arr = JSON.parse(s);
        newQKey.keyType = arr[0];
        newQKey.localName = arr[1];

    }
    catch (e)
    {
        console.log("Failed to parse string as a QKey array, assuming generic string key.", e);
        newQKey.keyType = "string";
        newQKey.localName = s;
    }
    return newQKey;
};

/**
 * Creates a new property of the specified type, and binds the appropriate callback.
 * @param name The name of the new property or previously existing property to access.
 * @param type The session state object type of the new property.
 * @param callback A callback taking no arguments to be called when the newly created property changes.
 * @return The current WeavePath object.
 */
weave.WeavePath.prototype.newProperty = function(name, type, callback)
{
    this.push(name).request(type).addCallback(callback, true);
    return this;
};

weave.WeavePath.prototype.getKeys = function(/* [name] */)
{
    var raw_keys = this.weave.evaluateExpression(this._path.concat(this._A(arguments, 1)), "this.keys", this._vars);
    var length = raw_keys.length;
    var result = new Array(length);
    for (var idx = 0; idx < length; idx++)
    {
        result[idx] = this.qkeyToString(raw_keys[idx]);
    }
    return result;
};

weave.WeavePath.prototype.setKeys = function(/* [name], keyStringArray */)
{
    var args = this._A(arguments, 2);
    if (this._assertParams('setKeys', args))
    {
        var keyStringArray = args.pop();
        var length = keyStringArray.length;
        var keyObjectArray = new Array(length);

        for (var idx = 0; idx < length; idx++)
        {
            keyObjectArray[idx] = this.stringToQKey(keyStringArray[idx]);
        }
        this.push(args).vars({setKeysArgs: keyObjectArray}).exec('replaceKeys(setKeysArgs)');
        return this;
    };
    return this;
};
weave.WeavePath.prototype.filterKeys = function (/* [name], keyStringArray */)
{
    var args = this._A(arguments, 2);
    if (this._assertParams('containsKeys', args))
    {
        var keyStringArray = args.pop();
        var keyObjects = keyStringArray.map(this.stringToQKey, this);
        var resultArray = this.push(args).libs("weave.api.WeaveAPI").vars({containsKeysArgs: keyObjects}).getValue(
            'WeaveAPI.QKeyManager.convertToQKeys(containsKeysArgs).filter(function(d) { return containsKey(d); })'
        );
        return resultArray.map(this.qkeyToString, this);
    }
}
@@ -1531,20 +1531,23 @@
 ion(/* %5B
-name
+relpath
 %5D */)%0A%7B%0A
@@ -1912,28 +1912,31 @@
 unction(/* %5B
-name
+relpath
 %5D, keyString
@@ -2506,20 +2506,23 @@
 on (/* %5B
-name
+relpath
 %5D, keySt
@@ -2603,24 +2603,22 @@
 Params('
-contains
+filter
 Keys', a
@@ -3046,8 +3046,634 @@
 %0A    %7D%0A%7D
+%0Aweave.WeavePath.prototype.retrieveColumns = function(/* %5Brelpath%5D, columnNameArray */)%0A%7B%0A    var args = this._A(arguments, 2);%0A    if (this._assertParams('retrieveColumns', args))%0A    %7B%0A        var columnNameArray = args.pop();%0A%0A        var results = this.push(args).libs(%22weave.utils.ColumnUtils%22).vars(%7BretrieveColumnsArgs: columnNameArray%7D).getValue(%0A            'ColumnUtils.joinColumns(retrieveColumnsArgs.map(function(name)%7B return getObject(name); %7D, this),  null, true)'%0A        );%0A        /* Convert the keys to strings */%0A        results%5B0%5D = results%5B0%5D.map(this.qkeyToString, this);%0A        return results;%0A    %7D%0A%7D

Add retrieveColumns function to WeavePathData