convert(tile, data, from, ...to) {
        const conversionPath = this.getConversionPath(from, to);
        if (!conversionPath) {
            $.console.error(`[OpenSeadragon.converter.convert] Conversion ${from} ---> ${to} cannot be done!`);
            return $.Promise.resolve();
        }

        const stepCount = conversionPath.length,
            _this = this;
        const step = (x, i, destroy = true) => {
            if (i >= stepCount) {
                return $.Promise.resolve(x);
            }
            let edge = conversionPath[i];
            let y = edge.transform(tile, x);
            if (y === undefined) {
                $.console.error(`[OpenSeadragon.converter.convert] data mid result undefined value (while converting using %s)`, edge);
                return $.Promise.resolve();
            }
            //node.value holds the type string
            if (destroy) {
                _this.destroy(x, edge.origin.value);
            }
            const result = $.type(y) === "promise" ? y : $.Promise.resolve(y);
            return result.then(res => step(res, i + 1));
        };
        //destroy only mid-results, but not the original value
        return step(data, 0, false);
    }
Convert data item x of type 'from' to any of the 'to' types, chosen is the cheapest known conversion.
Data is destroyed upon conversion. For different behavior, implement your conversion using the
path rules obtained from getConversionPath().
Note: conversion DOES NOT COPY data if [to] contains type 'from' (e.g., the cheapest conversion is no conversion).
It automatically calls destructor on immediate types, but NOT on the x and the result. You should call these
manually if these should be destroyed.
@param {OpenSeadragon.Tile} tile
@param {any} data data item to convert
@param {string} from data item type
@param {string} to desired type(s)
@return {OpenSeadragon.Promise<?>} promise resolution with type 'to' or undefined if the conversion failed