Implements the node resolution for folder access and extension selection
434634
function applyNodeExtensionResolution(unqualifiedPath, {extensions}) {
  // We use this "infinite while" so that we can restart the process as long as we hit package folders
  while (true) {
    let stat;

    try {
      stat = statSync(unqualifiedPath);
    } catch (error) {}

    // If the file exists and is a file, we can stop right there

    if (stat && !stat.isDirectory()) {
      // If the very last component of the resolved path is a symlink to a file, we then resolve it to a file. We only
      // do this first the last component, and not the rest of the path! This allows us to support the case of bin
      // symlinks, where a symlink in "/xyz/pkg-name/.bin/bin-name" will point somewhere else (like "/xyz/pkg-name/index.js").
      // In such a case, we want relative requires to be resolved relative to "/xyz/pkg-name/" rather than "/xyz/pkg-name/.bin/".
      //
      // Also note that the reason we must use readlink on the last component (instead of realpath on the whole path)
      // is that we must preserve the other symlinks, in particular those used by pnp to deambiguate packages using
      // peer dependencies. For example, "/xyz/.pnp/local/pnp-01234569/.bin/bin-name" should see its relative requires
      // be resolved relative to "/xyz/.pnp/local/pnp-0123456789/" rather than "/xyz/pkg-with-peers/", because otherwise
      // we would lose the information that would tell us what are the dependencies of pkg-with-peers relative to its
      // ancestors.

      if (lstatSync(unqualifiedPath).isSymbolicLink()) {
        unqualifiedPath = path.normalize(path.resolve(path.dirname(unqualifiedPath), readlinkSync(unqualifiedPath)));
      }

      return unqualifiedPath;
    }

    // If the file is a directory, we must check if it contains a package.json with a "main" entry

    if (stat && stat.isDirectory()) {
      let pkgJson;

      try {
        pkgJson = JSON.parse(readFileSync(`${unqualifiedPath}/package.json`, 'utf-8'));
      } catch (error) {}

      let nextUnqualifiedPath;

      if (pkgJson && pkgJson.main) {
        nextUnqualifiedPath = path.resolve(unqualifiedPath, pkgJson.main);
      }

      // If the "main" field changed the path, we start again from this new location

      if (nextUnqualifiedPath && nextUnqualifiedPath !== unqualifiedPath) {
        const resolution = applyNodeExtensionResolution(nextUnqualifiedPath, {extensions});

        if (resolution !== null) {
          return resolution;
        }
      }
    }

    // Otherwise we check if we find a file that match one of the supported extensions

    const qualifiedPath = extensions
      .map(extension => {
        return `${unqualifiedPath}${extension}`;
      })
      .find(candidateFile => {
        return existsSync(candidateFile);
      });

    if (qualifiedPath) {
      return qualifiedPath;
    }

    // Otherwise, we check if the path is a folder - in such a case, we try to use its index

    if (stat && stat.isDirectory()) {
      const indexPath = extensions
        .map(extension => {
          return `${unqualifiedPath}/index${extension}`;
        })
        .find(candidateFile => {
          return existsSync(candidateFile);
        });

      if (indexPath) {
        return indexPath;
      }
    }

    // Otherwise there's nothing else we can do :(

    return null;
  }
}
486808
public static void generateExplorerTypesXml(
        Element startNode,
        List<CmsExplorerTypeSettings> explorerTypes,
        boolean module) {

        // we need the default access node later to check if the explorer type is an individual setting
        CmsExplorerTypeAccess defaultAccess = null;
        if (OpenCms.getWorkplaceManager() != null) {
            defaultAccess = OpenCms.getWorkplaceManager().getDefaultAccess();
        }
        // get the menu rule translator to eliminate eventual legacy menu rules
        Iterator<CmsExplorerTypeSettings> i = explorerTypes.iterator();
        while (i.hasNext()) {
            // create an explorer type node
            CmsExplorerTypeSettings settings = i.next();

            if (settings.isAddititionalModuleExplorerType() == module) {
                Element explorerTypeElement = startNode.addElement(N_EXPLORERTYPE);
                explorerTypeElement.addAttribute(A_NAME, settings.getName());
                explorerTypeElement.addAttribute(A_KEY, settings.getKey());
                String originalIcon = settings.getOriginalIcon();
                if (CmsStringUtil.isNotEmpty(originalIcon)) {
                    explorerTypeElement.addAttribute(A_ICON, settings.getOriginalIcon());
                }
                if (CmsStringUtil.isNotEmpty(settings.getBigIcon())) {
                    explorerTypeElement.addAttribute(A_BIGICON, settings.getBigIcon());
                }
                if (CmsStringUtil.isNotEmpty(settings.getSmallIconStyle())) {
                    explorerTypeElement.addAttribute(A_SMALLICONSTYLE, settings.getSmallIconStyle());
                }
                if (CmsStringUtil.isNotEmpty(settings.getBigIconStyle())) {
                    explorerTypeElement.addAttribute(A_BIGICONSTYLE, settings.getBigIconStyle());
                }

                if (settings.getReference() != null) {
                    explorerTypeElement.addAttribute(A_REFERENCE, settings.getReference());
                }

                if (settings.getElementView() != null) {
                    explorerTypeElement.addAttribute(A_ELEMENTVIEW, settings.getElementView());
                }

                if (settings.isView()) {
                    explorerTypeElement.addAttribute(A_ISVIEW, "true");
                }

                if (settings.getNamePattern() != null) {
                    explorerTypeElement.addAttribute(A_NAME_PATTERN, settings.getNamePattern());
                }

                if (settings.getViewOrder(false) != null) {
                    explorerTypeElement.addAttribute(A_VIEW_ORDER, "" + settings.getViewOrder(false));
                }

                // create subnode <newresource>
                Element newResElement = explorerTypeElement.addElement(N_NEWRESOURCE);
                newResElement.addAttribute(A_CREATABLE, String.valueOf(settings.isCreatable()));
                newResElement.addAttribute(A_ORDER, settings.getNewResourceOrder());
                newResElement.addAttribute(A_AUTOSETNAVIGATION, String.valueOf(settings.isAutoSetNavigation()));
                newResElement.addAttribute(A_AUTOSETTITLE, String.valueOf(settings.isAutoSetTitle()));
                newResElement.addAttribute(A_INFO, settings.getInfo());
                newResElement.addAttribute(A_KEY, settings.getTitleKey());
                // create subnode <accesscontrol>
                CmsExplorerTypeAccess access = settings.getAccess();
                if (access != defaultAccess) {
                    // don't output the node if this is in fact the default access settings
                    List<String> accessEntries = new ArrayList<String>(access.getAccessEntries().keySet());
                    // sort accessEntries
                    Collections.sort(accessEntries);
                    if (accessEntries.size() > 0) {
                        Element accessControlElement = explorerTypeElement.addElement(N_ACCESSCONTROL);
                        Iterator<String> k = accessEntries.iterator();
                        while (k.hasNext()) {
                            String key = k.next();
                            String value = settings.getAccess().getAccessEntries().get(key);
                            Element accessEntryElement = accessControlElement.addElement(N_ACCESSENTRY);
                            accessEntryElement.addAttribute(A_PRINCIPAL, key);
                            accessEntryElement.addAttribute(A_PERMISSIONS, value);
                        }
                    }
                }
                // create subnode <editoptions>
                if (settings.hasEditOptions()) {
                    Element editOptionsElement = explorerTypeElement.addElement(N_EDITOPTIONS);
                    Element defaultPropertiesElement = editOptionsElement.addElement(N_DEFAULTPROPERTIES);
                    defaultPropertiesElement.addAttribute(A_ENABLED, String.valueOf(settings.isPropertiesEnabled()));
                    defaultPropertiesElement.addAttribute(
                        A_SHOWNAVIGATION,
                        String.valueOf(settings.isShowNavigation()));
                    Iterator<String> m = settings.getProperties().iterator();
                    while (m.hasNext()) {
                        defaultPropertiesElement.addElement(N_DEFAULTPROPERTY).addAttribute(A_NAME, m.next());
                    }
                }

                Map<String, CmsIconRule> iconRules = settings.getIconRules();
                if ((iconRules != null) && !iconRules.isEmpty()) {
                    Element iconRulesElem = explorerTypeElement.addElement(N_ICONRULES);
                    for (Map.Entry<String, CmsIconRule> entry : iconRules.entrySet()) {
                        CmsIconRule rule = entry.getValue();
                        Element ruleElem = iconRulesElem.addElement(N_ICONRULE);
                        String icon = rule.getIcon();
                        String bigIcon = rule.getBigIcon();
                        String extension = rule.getExtension();
                        ruleElem.addAttribute(A_EXTENSION, extension);
                        if (icon != null) {
                            ruleElem.addAttribute(A_ICON, icon);
                        }
                        if (bigIcon != null) {
                            ruleElem.addAttribute(A_BIGICON, bigIcon);
                        }
                        if (rule.getSmallIconStyle() != null) {
                            ruleElem.addAttribute(A_SMALLICONSTYLE, rule.getSmallIconStyle());
                        }
                        if (rule.getBigIconStyle() != null) {
                            ruleElem.addAttribute(A_BIGICONSTYLE, rule.getBigIconStyle());
                        }
                    }
                }

            }
        }
    }
467758
function(protocol, name, host, opt) {
		var noOffline = typeof opt === 'boolean'? opt : null, // for backward compat
			opts = Object.assign({
				noOffline : false,
				root      : 'root',
				pathI18n  : 'folderId',
				folders   : true
			}, (noOffline === null? (opt || {}) : {noOffline : noOffline})),
			addFolders = function(fm, bro, folders) {
				var self = this,
					cnt  = Object.keys($.isPlainObject(folders)? folders : {}).length,
					select;
				
				bro.next().remove();
				if (cnt) {
					select = $('<select class="ui-corner-all elfinder-tabstop" style="max-width:200px;">').append(
						$($.map(folders, function(n,i){return '<option value="'+fm.escape((i+'').trim())+'">'+fm.escape(n)+'</option>';}).join(''))
					).on('change click', function(e){
						var node = $(this),
							path = node.val(),
							spn;
						self.inputs.path.val(path);
						if (opts.folders && (e.type === 'change' || node.data('current') !== path)) {
							node.next().remove();
							node.data('current', path);
							if (path != opts.root) {
								spn = spinner();
								if (xhr && xhr.state() === 'pending') {
									fm.abortXHR(xhr, { quiet: true , abort: true });
								}
								node.after(spn);
								xhr = fm.request({
									data : {cmd : 'netmount', protocol: protocol, host: host, user: 'init', path: path, pass: 'folders'},
									preventDefault : true
								}).done(function(data){
									addFolders.call(self, fm, node, data.folders);
								}).always(function() {
									fm.abortXHR(xhr, { quiet: true });
									spn.remove();
								}).xhr;
							}
						}
					});
					bro.after($('<div/>').append(select))
						.closest('.ui-dialog').trigger('tabstopsInit');
					select.trigger('focus');
				}
			},
			spinner = function() {
				return $('<div class="elfinder-netmount-spinner"/>').append('<span class="elfinder-info-spinner"/>');
			},
			xhr;
		return {
			vars : {},
			name : name,
			inputs: {
				offline  : $('<input type="checkbox"/>').on('change', function() {
					$(this).parents('table.elfinder-netmount-tb').find('select:first').trigger('change', 'reset');
				}),
				host     : $('<span><span class="elfinder-info-spinner"/></span><input type="hidden"/>'),
				path     : $('<input type="text" value="'+opts.root+'"/>'),
				user     : $('<input type="hidden"/>'),
				pass     : $('<input type="hidden"/>')
			},
			select: function(fm, ev, d){
				var f = this.inputs,
					oline = f.offline,
					f0 = $(f.host[0]),
					data = d || null;
				this.vars.mbtn = f.host.closest('.ui-dialog').children('.ui-dialog-buttonpane:first').find('button.elfinder-btncnt-0');
				if (! f0.data('inrequest')
						&& (f0.find('span.elfinder-info-spinner').length
							|| data === 'reset'
							|| (data === 'winfocus' && ! f0.siblings('span.elfinder-button-icon-reload').length))
							)
				{
					if (oline.parent().children().length === 1) {
						f.path.parent().prev().html(fm.i18n(opts.pathI18n));
						oline.attr('title', fm.i18n('offlineAccess'));
						oline.uniqueId().after($('<label/>').attr('for', oline.attr('id')).html(' '+fm.i18n('offlineAccess')));
					}
					f0.data('inrequest', true).empty().addClass('elfinder-info-spinner')
						.parent().find('span.elfinder-button-icon').remove();
					fm.request({
						data : {cmd : 'netmount', protocol: protocol, host: host, user: 'init', options: {id: fm.id, offline: oline.prop('checked')? 1:0, pass: f.host[1].value}},
						preventDefault : true
					}).done(function(data){
						f0.removeClass("elfinder-info-spinner").html(data.body.replace(/\{msg:([^}]+)\}/g, function(whole,s1){return fm.i18n(s1, host);}));
					});
					opts.noOffline && oline.closest('tr').hide();
				} else {
					oline.closest('tr')[(opts.noOffline || f.user.val())? 'hide':'show']();
					f0.data('funcexpup') && f0.data('funcexpup')();
				}
				this.vars.mbtn[$(f.host[1]).val()? 'show':'hide']();
			},
			done: function(fm, data){
				var f = this.inputs,
					p = this.protocol,
					f0 = $(f.host[0]),
					f1 = $(f.host[1]),
					expires = '&nbsp;';
				
				opts.noOffline && f.offline.closest('tr').hide();
				if (data.mode == 'makebtn') {
					f0.removeClass('elfinder-info-spinner').removeData('expires').removeData('funcexpup');
					f.host.find('input').on('mouseenter mouseleave', function(){$(this).toggleClass('ui-state-hover');});
					f1.val('');
					f.path.val(opts.root).next().remove();
					f.user.val('');
					f.pass.val('');
					! opts.noOffline && f.offline.closest('tr').show();
					this.vars.mbtn.hide();
				} else if (data.mode == 'folders') {
					if (data.folders) {
						addFolders.call(this, fm, f.path.nextAll(':last'), data.folders);
					}
				} else {
					if (data.expires) {
						expires = '()';
						f0.data('expires', data.expires);
					}
					f0.html(host + expires).removeClass('elfinder-info-spinner');
					if (data.expires) {
						f0.data('funcexpup', function() {
							var rem = Math.floor((f0.data('expires') - (+new Date()) / 1000) / 60);
							if (rem < 3) {
								f0.parent().children('.elfinder-button-icon-reload').click();
							} else {
								f0.text(f0.text().replace(/\(.*\)/, '('+fm.i18n(['minsLeft', rem])+')'));
								setTimeout(function() {
									if (f0.is(':visible')) {
										f0.data('funcexpup')();
									}
								}, 60000);
							}
						});
						f0.data('funcexpup')();
					}
					if (data.reset) {
						p.trigger('change', 'reset');
						return;
					}
					f0.parent().append($('<span class="elfinder-button-icon elfinder-button-icon-reload" title="'+fm.i18n('reAuth')+'">')
						.on('click', function() {
							f1.val('reauth');
							p.trigger('change', 'reset');
						}));
					f1.val(protocol);
					this.vars.mbtn.show();
					if (data.folders) {
						addFolders.call(this, fm, f.path, data.folders);
					}
					f.user.val('done');
					f.pass.val('done');
					f.offline.closest('tr').hide();
				}
				f0.removeData('inrequest');
			},
			fail: function(fm, err){
				$(this.inputs.host[0]).removeData('inrequest');
				this.protocol.trigger('change', 'reset');
			},
			integrateInfo: opts.integrate
		};
	}
1097119
@Override
	public void addNode(Node n) {
		if (nodeAccess.getCapacity() < getNodeIndex(nodePos) + NODE_SIZE)
			nodeAccess.ensureCapacity(nodeAccess.getCapacity() + INITIAL_NODE_FILE_SIZE);
		nodIdMapping.put(n.getId(), nodePos);
		
		long nodeIndex = getNodeIndex(nodePos);
		
		nodeAccess.setLong( nodeIndex      , n.getId() );
		nodeAccess.setLong( nodeIndex + 8  ,    -1l    );
		nodeAccess.setLong( nodeIndex + 16 ,    -1l    );
		
		nodeAccess.setLong( 0 , ++nodePos );
		
	}
706772
def root(current, indent)
      if KEYWORDS.include? current[@type]
        send :"#{current[@type]}_node", current, indent
      else
        send current[@type], current, indent
      end
    end
663898
def format_file_node(import_graph, node, indent):
    """"""
    f = import_graph.provenance[node]
    if isinstance(f, resolve.Direct):
        out = '+ ' + f.short_path
    elif isinstance(f, resolve.Local):
        out = '  ' + f.short_path
    elif isinstance(f, resolve.System):
        out = ':: ' + f.short_path
    elif isinstance(f, resolve.Builtin):
        out = '(%s)' % f.module_name
    else:
        out = '%r' % node
    return '  '*indent + out
586860
public boolean visit(MethodInvocation node)
    {
        if (!StringUtils.contains(node.toString(), "."))
        {
            // it must be a local method. ignore.
            return true;
        }
        List<String> qualifiedInstances = new ArrayList<>();
        List<String> argumentsQualified = new ArrayList<>();
        // get qualified arguments of the method
        IMethodBinding resolveTypeBinding = node.resolveMethodBinding();
        final ResolutionStatus resolutionStatus;
        int columnNumber = compilationUnit.getColumnNumber(node.getName().getStartPosition());
        int length = node.getName().getLength();
        if (resolveTypeBinding != null)
        {
            resolutionStatus = ResolutionStatus.RESOLVED;
            ITypeBinding[] argumentTypeBindings = resolveTypeBinding.getParameterTypes();
            List<Expression> arguments = node.arguments();
            int index = 0;
            for (ITypeBinding type : argumentTypeBindings)
            {
                argumentsQualified.add(type.getQualifiedName());

                if (type.isEnum())
                {
                    // there is different number of passed arguments and possible arguments from declaration
                    if (arguments.size() > index)
                    {
                        Expression expression = arguments.get(index);
                        processTypeAsEnum(type, expression, resolutionStatus,
                                compilationUnit.getLineNumber(node.getName().getStartPosition()),
                                columnNumber,
                                length, extractDefinitionLine(node.toString()));
                    }
                    index++;
                }
            }

            // find the interface declaring the method
            if (resolveTypeBinding != null && resolveTypeBinding.getDeclaringClass() != null)
            {
                ITypeBinding declaringClass = resolveTypeBinding.getDeclaringClass();
                qualifiedInstances.add(declaringClass.getQualifiedName());
                ITypeBinding[] interfaces = declaringClass.getInterfaces();
                // Now find all the implemented interfaces having the method called.
                for (ITypeBinding possibleInterface : interfaces)
                {
                    IMethodBinding[] declaredMethods = possibleInterface.getDeclaredMethods();
                    if (declaredMethods.length != 0)
                    {
                        for (IMethodBinding interfaceMethod : declaredMethods)
                        {
                            if (interfaceMethod.getName().equals(node.getName().toString()))
                            {
                                List<String> interfaceMethodArguments = new ArrayList<>();
                                for (ITypeBinding type : interfaceMethod.getParameterTypes())
                                {
                                    interfaceMethodArguments.add(type.getQualifiedName());
                                }
                                if (interfaceMethodArguments.equals(argumentsQualified))
                                {
                                    qualifiedInstances.add(possibleInterface.getQualifiedName());
                                }
                            }
                        }
                    }
                }
            }

        }
        else
        {
            resolutionStatus = ResolutionStatus.RECOVERED;
            String nodeName = StringUtils.removeStart(node.toString(), "this.");
            String objRef = StringUtils.substringBefore(nodeName, "." + node.getName().toString());
            if (state.getNameInstance().containsKey(objRef))
            {
                objRef = state.getNameInstance().get(objRef);
            }
            objRef = resolveClassname(objRef).result;

            @SuppressWarnings("unchecked")
            List<Expression> arguments = node.arguments();
            for (Expression expression : arguments)
            {
                ITypeBinding argumentBinding = expression.resolveTypeBinding();
                if (argumentBinding != null)
                {
                    argumentsQualified.add(argumentBinding.getQualifiedName());

                    if (argumentBinding.isEnum())
                    {
                        // FIXME -- Test
                        String constantEnum = expression.toString();
                        if (constantEnum != null)
                        {
                            processTypeAsEnum(argumentBinding, expression, ResolutionStatus.RESOLVED, compilationUnit.getLineNumber(node.getName().getStartPosition()),
                                    columnNumber, length, extractDefinitionLine(node.toString()));
                        }
                    }
                }
                else
                {
                    PackageAndClassName argumentQualifiedGuess = PackageAndClassName.parseFromQualifiedName(expression.toString());
                    argumentsQualified.add(argumentQualifiedGuess.toString());
                }
            }
            qualifiedInstances.add(objRef);
        }

        for (String qualifiedInstance : qualifiedInstances)
        {
            PackageAndClassName packageAndClassName = PackageAndClassName.parseFromQualifiedName(qualifiedInstance);
            MethodType methodCall = new MethodType(qualifiedInstance, packageAndClassName.packageName, packageAndClassName.className,
                        node.getName().toString(), argumentsQualified);
            processMethod(methodCall, resolutionStatus, TypeReferenceLocation.METHOD_CALL,
                        compilationUnit.getLineNumber(node.getName().getStartPosition()),
                        columnNumber, length, node.toString());
        }

        return super.visit(node);
    }
805833
def visit_extslice(self, node):
        """"""
        return ", ".join(dim.accept(self) for dim in node.dims)
833745
def get_files_with_extensions(folder, extensions):
    """"""
    out = []
    for root, dirs, files in os.walk(folder):
        for file in files:
            filename, file_extension = os.path.splitext(file)
            if file_extension.replace(".", "") in extensions:
                out += [os.path.join(root, file)]
                # break

    return out
672849
function(root, path) {
				if (path.indexOf(this.SEPARATOR) === 0) {
					root = this.rootNode;
					path = path.substring(1);
				} else {
					if (!root) {
						if (!this.currentDirectory) {
							/* no node to resolve the path in terms of */
							return null;
						}
						root = this.currentDirectory;
					}
				}
				var segments = path.substring(0, path.lastIndexOf(this.SEPARATOR)).split(this.SEPARATOR);
				var result = root;
				for (var i = 0; i < segments.length; i++) {
					if (segments[i].length > 0) {
						result = this.getChild(result, segments[i]);
						if (!result || !result.Directory) {
							/* non-existent directory */
							return null;
						}
					}
				}

				/*
				 * If the full path represents a directory then initiate the
				 * retrieval of its full node info and children.
				 */
				var lastSegment = path.substring(path.lastIndexOf(this.SEPARATOR) + 1);
				var child = this.getChild(result, lastSegment);
				if (child) {
					this._retrieveNode(child);
				}

				if (!result.Children) {
					this._retrieveNode(result);
				}
				return result;
			}
1222291
function dispatch(methodName, inDocument, xpath, contextNode, namespaceResolver) {
        xpath = preprocess(xpath);

        if (! contextNode) {
            contextNode = inDocument;
        }

        var result = getEngineFor(inDocument)
            .setIgnoreAttributesWithoutValue(ignoreAttributesWithoutValue)
            [methodName](xpath, contextNode, namespaceResolver);

        return result;
    }
950224
private void processCheckExpandedCustomNodes(final TreeItemIdNode node, final Set<String> expandedRows) {
		// Node has no children
		if (!node.hasChildren()) {
			return;
		}

		// Check node is expanded
		boolean expanded = getExpandMode() == WTree.ExpandMode.CLIENT || expandedRows.contains(node.getItemId());
		if (!expanded) {
			return;
		}

		if (node.getChildren().isEmpty()) {
			// Add children from the model
			loadCustomNodeChildren(node);
		} else {
			// Check the expanded child nodes
			for (TreeItemIdNode child : node.getChildren()) {
				processCheckExpandedCustomNodes(child, expandedRows);
			}
		}
	}
402750
private void applyPathsDocumentExtension(Context context) {
        extensionRegistry.getPathsDocumentExtensions().forEach(extension -> extension.apply(context));
    }
593394
public static AccessibilityNodeInfoCompat refreshNode(
        AccessibilityNodeInfoCompat node) {
        if (node == null) {
            return null;
        }
        AccessibilityNodeInfoCompat result = refreshFromChild(node);
        if (result == null) {
            result = refreshFromParent(node);
        }
        return result;
    }
910221
protected function checkEdgeDir(string $node_name): void
    {
        $dirname = $this->folder.DIRECTORY_SEPARATOR.$node_name."Out";
        if(!file_exists($dirname)) {
            throw new Exceptions\AbsentEdgeDirImparityException($dirname, $node_name);
        }
    }
468283
function(ctx) {
				var activate,
					expand,
					// event = ctx.originalEvent,
					targetType = ctx.targetType,
					node = ctx.node;

				// this.debug("ftnode.onClick(" + event.type + "): ftnode:" + this + ", button:" + event.button + ", which: " + event.which, ctx);
				// TODO: use switch
				// TODO: make sure clicks on embedded <input> doesn't steal focus (see table sample)
				if (targetType === "expander") {
					if (node.isLoading()) {
						// #495: we probably got a click event while a lazy load is pending.
						// The 'expanded' state is not yet set, so 'toggle' would expand
						// and trigger lazyLoad again.
						// It would be better to allow to collapse/expand the status node
						// while loading (instead of ignoring), but that would require some
						// more work.
						node.debug("Got 2nd click while loading: ignored");
						return;
					}
					// Clicking the expander icon always expands/collapses
					this._callHook("nodeToggleExpanded", ctx);
				} else if (targetType === "checkbox") {
					// Clicking the checkbox always (de)selects
					this._callHook("nodeToggleSelected", ctx);
					if (ctx.options.focusOnSelect) {
						// #358
						this._callHook("nodeSetFocus", ctx, true);
					}
				} else {
					// Honor `clickFolderMode` for
					expand = false;
					activate = true;
					if (node.folder) {
						switch (ctx.options.clickFolderMode) {
							case 2: // expand only
								expand = true;
								activate = false;
								break;
							case 3: // expand and activate
								activate = true;
								expand = true; //!node.isExpanded();
								break;
							// else 1 or 4: just activate
						}
					}
					if (activate) {
						this.nodeSetFocus(ctx);
						this._callHook("nodeSetActive", ctx, true);
					}
					if (expand) {
						if (!activate) {
							// this._callHook("nodeSetFocus", ctx);
						}
						// this._callHook("nodeSetExpanded", ctx, true);
						this._callHook("nodeToggleExpanded", ctx);
					}
				}
				// Make sure that clicks stop, otherwise <a href='#'> jumps to the top
				// if(event.target.localName === "a" && event.target.className === "fancytree-title"){
				// 	event.preventDefault();
				// }
				// TODO: return promise?
			}
779816
private void handleCandidateProvideDefinition(NodeTraversal t, Node n, Node parent) {
    if (t.inGlobalHoistScope()) {
      String name = null;
      if (n.isName() && NodeUtil.isNameDeclaration(parent)) {
        name = n.getString();
      } else if (n.isAssign() && parent.isExprResult()) {
        name = n.getFirstChild().getQualifiedName();
      }

      if (name != null) {
        if (parent.getBooleanProp(Node.IS_NAMESPACE)) {
          // TODO(b/128361464): stop including goog.module exports in this case.
          processProvideFromPreviousPass(t, name, parent);
        } else {
          ProvidedName pn = providedNames.get(name);
          if (pn != null) {
            pn.addDefinition(parent, t.getModule());
          }
        }
      }
    }
  }