From 18fdc285483e20ff4776b6e504830d7da0756c7a Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Thu, 22 Oct 2009 18:21:22 +0400 Subject: [PATCH 1/5] TreeUi: extract notfications fixed --- .../ide/util/treeView/AbstractTreeUi.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java index de3f641c4511..c84a46b90cf4 100644 --- a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java +++ b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java @@ -204,7 +204,7 @@ public class AbstractTreeUi { } - private boolean isNodeActionsPending() { + boolean isNodeActionsPending() { return !myNodeActions.isEmpty() || !myNodeChildrenActions.isEmpty(); } @@ -1235,7 +1235,7 @@ public class AbstractTreeUi { } public boolean isReady() { - return isIdle() && !hasPendingWork(); + return isIdle() && !hasPendingWork() && !isNodeActionsPending(); } public boolean hasPendingWork() { @@ -1750,11 +1750,11 @@ public class AbstractTreeUi { final Object element = getBuilder().getTreeStructureElement((NodeDescriptor)o); - processActions(node, element, myNodeActions); - boolean childrenReady = !isLoadedInBackground(element); + + processActions(node, element, myNodeActions, childrenReady ? myNodeChildrenActions : null); if (childrenReady) { - processActions(node, element, myNodeChildrenActions); + processActions(node, element, myNodeChildrenActions, null); } if (!isUpdatingParent(node) && !isWorkerBusy()) { @@ -1770,11 +1770,16 @@ public class AbstractTreeUi { } - private void processActions(DefaultMutableTreeNode node, Object element, final Map> nodeActions) { + private void processActions(DefaultMutableTreeNode node, Object element, final Map> nodeActions, @Nullable final Map> secondaryNodeAction) { final List actions = nodeActions.get(element); if (actions != null) { nodeActions.remove(element); + + List secondary = secondaryNodeAction != null ? secondaryNodeAction.get(element) : null; for (NodeAction each : actions) { + if (secondary != null && secondary.contains(each)) { + secondary.remove(each); + } each.onReady(node); } } From e1a795a3a9a3c555a553fc02b4480410be957e0c Mon Sep 17 00:00:00 2001 From: Roman Chernyatchik Date: Thu, 22 Oct 2009 23:07:28 +0400 Subject: [PATCH 2/5] 1. utility class was renamed. 2. location provider util class was refactored for smarter file search algorithm --- .../testframework/sm/FileUrlProvider.java | 7 +- .../sm/LocationProviderUtil.java | 68 ---------- .../sm/TestsLocationProviderUtil.java | 120 ++++++++++++++++++ .../testframework/sm/runner/SMTestProxy.java | 6 +- .../sm/LocationProviderUtilTest.java | 28 ++-- 5 files changed, 142 insertions(+), 87 deletions(-) delete mode 100644 platform/smRunner/src/com/intellij/execution/testframework/sm/LocationProviderUtil.java create mode 100644 platform/smRunner/src/com/intellij/execution/testframework/sm/TestsLocationProviderUtil.java diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/FileUrlProvider.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/FileUrlProvider.java index 08ce764029b9..22cd2f4e7fac 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/FileUrlProvider.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/FileUrlProvider.java @@ -20,6 +20,7 @@ import com.intellij.execution.PsiLocation; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.testIntegration.TestLocationProvider; @@ -71,8 +72,10 @@ public class FileUrlProvider implements TestLocationProvider { lineNumber = 1; filePath = normalizedPath; } - //Now we should seach file with most sutable path - final List virtualFiles = LocationProviderUtil.findSuitableFilesFor(filePath); + // Now we should search file with most suitable path + // here path may be absolute or relative + final String systemIndependentPath = FileUtil.toSystemIndependentName(filePath); + final List virtualFiles = TestsLocationProviderUtil.findSuitableFilesFor(systemIndependentPath, project); if (virtualFiles.isEmpty()) { return Collections.emptyList(); } diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/LocationProviderUtil.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/LocationProviderUtil.java deleted file mode 100644 index a83b0a432cbd..000000000000 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/LocationProviderUtil.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.execution.testframework.sm; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.NonNls; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.ex.temp.TempFileSystem; -import com.intellij.openapi.application.ApplicationManager; - -import java.util.List; -import java.util.Collections; - -/** - * @author Roman Chernyatchik - */ -public class LocationProviderUtil { - @NonNls private static final String PROTOCOL_SEPARATOR = "://"; - - private LocationProviderUtil() { - } - - @Nullable - public static String extractProtocol(@NotNull final String locationUrl) { - final int index = locationUrl.indexOf(PROTOCOL_SEPARATOR); - if (index >= 0) { - return locationUrl.substring(0, index); - } - return null; - } - - @Nullable - public static String extractPath(@NotNull final String locationUrl) { - final int index = locationUrl.indexOf(PROTOCOL_SEPARATOR); - if (index >= 0) { - return locationUrl.substring(index + PROTOCOL_SEPARATOR.length()); - } - return null; - } - - public static List findSuitableFilesFor(final String filePath) { - final VirtualFile fileByPath = LocalFileSystem.getInstance().findFileByPath(filePath); - if (fileByPath != null) { - return Collections.singletonList(fileByPath); - } - // if we are in UnitTest mode probably TempFileSystem is used instead of LocaFileSystem - if (ApplicationManager.getApplication().isUnitTestMode()) { - final VirtualFile tempFileByPath = TempFileSystem.getInstance().findFileByPath(filePath); - return Collections.singletonList(tempFileByPath); - } - return Collections.emptyList(); - } -} diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/TestsLocationProviderUtil.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/TestsLocationProviderUtil.java new file mode 100644 index 000000000000..9e3d71010bd0 --- /dev/null +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/TestsLocationProviderUtil.java @@ -0,0 +1,120 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.execution.testframework.sm; + +import com.intellij.navigation.ChooseByNameContributor; +import com.intellij.navigation.NavigationItem; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.ex.temp.TempFileSystem; +import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author Roman Chernyatchik + */ +public class TestsLocationProviderUtil { + @NonNls private static final String PROTOCOL_SEPARATOR = "://"; + + private TestsLocationProviderUtil() { + } + + @Nullable + public static String extractProtocol(@NotNull final String locationUrl) { + final int index = locationUrl.indexOf(PROTOCOL_SEPARATOR); + if (index >= 0) { + return locationUrl.substring(0, index); + } + return null; + } + + @Nullable + public static String extractPath(@NotNull final String locationUrl) { + final int index = locationUrl.indexOf(PROTOCOL_SEPARATOR); + if (index >= 0) { + return locationUrl.substring(index + PROTOCOL_SEPARATOR.length()); + } + return null; + } + + public static List findSuitableFilesFor(final String filePath, final Project project) { + final ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex(); + + // at first let's try to find file as is, by it's real path + // and check that file belongs to current project + // this location provider designed for tests thus we will check only project content + // (we cannot check just sources or tests folders because RM doesn't use it + final VirtualFile file = getByFullPath(filePath); + final boolean inProjectContent = file != null && (index.isInContent(file)); + + if (inProjectContent) { + return Collections.singletonList(file); + } + + //TODO: split file by "/" in parts + final List folders = new ArrayList(); + //TODO: + final String fileName = "foo.feature"; + + //otherwise let's find all files with the same name and similar relative path + final List items = new ArrayList(); + final ChooseByNameContributor[] contributors = Extensions.getExtensions(ChooseByNameContributor.FILE_EP_NAME); + for (ChooseByNameContributor contributor : contributors) { + // let's find files with same name in project and libraries + final NavigationItem[] navigationItems = contributor.getItemsByName(fileName, fileName, project, true); + for (NavigationItem navigationItem : navigationItems) { + if (navigationItem instanceof PsiFile) { + items.add(navigationItem); + } + } + } + //TODO let's filter psi files ... + + //TODO let's iterate relative path components and determine which files are closer to our relative path + // let's extract the closest files to relative path. For this we will sort items by distance and + // we also assume that relative files and folders should have at least one common parent folder - just to remove false positives on some cases + for (String folder : folders) { + + } + + return Collections.emptyList(); + } + + @Nullable + private static VirtualFile getByFullPath(String filePath) { + final VirtualFile fileByPath = LocalFileSystem.getInstance().findFileByPath(filePath); + if (fileByPath != null) { + return fileByPath; + } + // if we are in UnitTest mode probably TempFileSystem is used instead of LocaFileSystem + if (ApplicationManager.getApplication().isUnitTestMode()) { + final VirtualFile tempFileByPath = TempFileSystem.getInstance().findFileByPath(filePath); + return tempFileByPath; + } + return null; + } +} diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java index bcd9d679ed1c..8ffba72416ff 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java @@ -17,7 +17,7 @@ package com.intellij.execution.testframework.sm.runner; import com.intellij.execution.Location; import com.intellij.execution.testframework.*; -import com.intellij.execution.testframework.sm.LocationProviderUtil; +import com.intellij.execution.testframework.sm.TestsLocationProviderUtil; import com.intellij.execution.testframework.sm.runner.states.*; import com.intellij.execution.testframework.sm.runner.ui.TestsPresentationUtil; import com.intellij.execution.testframework.ui.PrintableTestProxy; @@ -136,8 +136,8 @@ public class SMTestProxy extends CompositePrintable implements PrintableTestProx return null; } - final String protocolId = LocationProviderUtil.extractProtocol(myLocationUrl); - final String path = LocationProviderUtil.extractPath(myLocationUrl); + final String protocolId = TestsLocationProviderUtil.extractProtocol(myLocationUrl); + final String path = TestsLocationProviderUtil.extractPath(myLocationUrl); if (protocolId != null && path != null) { for (TestLocationProvider provider : Extensions.getExtensions(TestLocationProvider.EP_NAME)) { diff --git a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/LocationProviderUtilTest.java b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/LocationProviderUtilTest.java index 32ea21b72cb7..dd2a99cfd2db 100644 --- a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/LocationProviderUtilTest.java +++ b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/LocationProviderUtilTest.java @@ -23,39 +23,39 @@ import com.intellij.testFramework.UsefulTestCase; public class LocationProviderUtilTest extends UsefulTestCase { public void testExtractProtocol() { assertEquals(null, - LocationProviderUtil.extractProtocol("")); + TestsLocationProviderUtil.extractProtocol("")); assertEquals(null, - LocationProviderUtil.extractProtocol("file:/")); + TestsLocationProviderUtil.extractProtocol("file:/")); assertEquals("file", - LocationProviderUtil.extractProtocol("file://")); + TestsLocationProviderUtil.extractProtocol("file://")); assertEquals("file", - LocationProviderUtil.extractProtocol("file:///some/path/file.rb:24")); + TestsLocationProviderUtil.extractProtocol("file:///some/path/file.rb:24")); assertEquals("file", - LocationProviderUtil.extractProtocol("file://./some/path/file.rb:24")); + TestsLocationProviderUtil.extractProtocol("file://./some/path/file.rb:24")); assertEquals("ruby_qn", - LocationProviderUtil.extractProtocol("ruby_qn://")); + TestsLocationProviderUtil.extractProtocol("ruby_qn://")); assertEquals("ruby_qn", - LocationProviderUtil.extractProtocol("ruby_qn://A::B.method")); + TestsLocationProviderUtil.extractProtocol("ruby_qn://A::B.method")); } public void testExtractPath() { assertEquals(null, - LocationProviderUtil.extractPath("")); + TestsLocationProviderUtil.extractPath("")); assertEquals(null, - LocationProviderUtil.extractPath("file:/")); + TestsLocationProviderUtil.extractPath("file:/")); assertEquals("", - LocationProviderUtil.extractPath("file://")); + TestsLocationProviderUtil.extractPath("file://")); assertEquals("/some/path/file.rb:24", - LocationProviderUtil.extractPath("file:///some/path/file.rb:24")); + TestsLocationProviderUtil.extractPath("file:///some/path/file.rb:24")); assertEquals("./some/path/file.rb:24", - LocationProviderUtil.extractPath("file://./some/path/file.rb:24")); + TestsLocationProviderUtil.extractPath("file://./some/path/file.rb:24")); assertEquals("", - LocationProviderUtil.extractPath("ruby_qn://")); + TestsLocationProviderUtil.extractPath("ruby_qn://")); assertEquals("A::B.method", - LocationProviderUtil.extractPath("ruby_qn://A::B.method")); + TestsLocationProviderUtil.extractPath("ruby_qn://A::B.method")); } } From 455d77552ea4883d03105755611d24a8df01002c Mon Sep 17 00:00:00 2001 From: Roman Chernyatchik Date: Fri, 23 Oct 2009 13:52:05 +0400 Subject: [PATCH 3/5] ability to search tests candidates in project content by relative path from TC agent --- .../sm/TestsLocationProviderUtil.java | 121 +++++++++++++++--- 1 file changed, 104 insertions(+), 17 deletions(-) diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/TestsLocationProviderUtil.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/TestsLocationProviderUtil.java index 9e3d71010bd0..4b589ddaf40b 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/TestsLocationProviderUtil.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/TestsLocationProviderUtil.java @@ -26,12 +26,14 @@ import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.ex.temp.TempFileSystem; import com.intellij.psi.PsiFile; +import com.intellij.util.text.StringTokenizer; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collections; +import java.util.LinkedList; import java.util.List; /** @@ -39,6 +41,7 @@ import java.util.List; */ public class TestsLocationProviderUtil { @NonNls private static final String PROTOCOL_SEPARATOR = "://"; + private static final int MIN_PROXIMITY_TRESHOLD = 1; private TestsLocationProviderUtil() { } @@ -72,36 +75,85 @@ public class TestsLocationProviderUtil { final boolean inProjectContent = file != null && (index.isInContent(file)); if (inProjectContent) { - return Collections.singletonList(file); + // TODO + //return Collections.singletonList(file); } - //TODO: split file by "/" in parts - final List folders = new ArrayList(); - //TODO: - final String fileName = "foo.feature"; + //split file by "/" in parts + final LinkedList folders = new LinkedList(); + final StringTokenizer st = new StringTokenizer(filePath, "/", false); + String fileName = null; + while (st.hasMoreTokens()) { + final String pathComponent = st.nextToken(); + if (st.hasMoreTokens()) { + folders.addFirst(pathComponent); + } else { + // last token + fileName = pathComponent; + } + } //otherwise let's find all files with the same name and similar relative path - final List items = new ArrayList(); + final List filesInfo = collectCandidates(project, fileName); + + if (filesInfo.isEmpty()) { + return Collections.emptyList(); + } + + // let's iterate relative path components and determine which files are closer to our relative path + for (String folderName : folders) { + for (FileInfo info : filesInfo) { + info.processRelativePathComponent(folderName); + } + } + + // let's extract the closest files to relative path. For this we will find max proximity and and + // we also assume that relative files and folders should have at least one common parent folder - just + // to remove false positives on some cases + int maxProximity = 0; + for (FileInfo fileInfo : filesInfo) { + final int proximity = fileInfo.getProximity(); + if (proximity > maxProximity) { + maxProximity = proximity; + } + } + + if (maxProximity >= MIN_PROXIMITY_TRESHOLD) { + final List files = new ArrayList(); + for (FileInfo info : filesInfo) { + if (info.getProximity() == maxProximity) { + files.add(info.getFile()); + } + } + return files; + } + + return Collections.emptyList(); + } + + //private static int compare(final FileInfo info1, final FileInfo info2) { + // final int proximity1 = info1.getProximity(); + // final int proximity2 = info2.getProximity(); + // + // return proximity2 - proximity1; + //} + + private static List collectCandidates(Project project, String fileName) { + final List filesInfo = new ArrayList(); final ChooseByNameContributor[] contributors = Extensions.getExtensions(ChooseByNameContributor.FILE_EP_NAME); for (ChooseByNameContributor contributor : contributors) { // let's find files with same name in project and libraries final NavigationItem[] navigationItems = contributor.getItemsByName(fileName, fileName, project, true); for (NavigationItem navigationItem : navigationItems) { if (navigationItem instanceof PsiFile) { - items.add(navigationItem); + final VirtualFile itemFile = ((PsiFile)navigationItem).getVirtualFile(); + assert itemFile != null; + + filesInfo.add(new FileInfo(itemFile)); } } } - //TODO let's filter psi files ... - - //TODO let's iterate relative path components and determine which files are closer to our relative path - // let's extract the closest files to relative path. For this we will sort items by distance and - // we also assume that relative files and folders should have at least one common parent folder - just to remove false positives on some cases - for (String folder : folders) { - - } - - return Collections.emptyList(); + return filesInfo; } @Nullable @@ -117,4 +169,39 @@ public class TestsLocationProviderUtil { } return null; } + + public static class FileInfo { + private final VirtualFile myFile; + private VirtualFile myCurrentFolder; + private int myProximity = 0; + + public FileInfo(VirtualFile file) { + myFile = file; + myCurrentFolder = myFile.getParent(); + } + + public void processRelativePathComponent(final String folderName) { + if (myCurrentFolder == null) { + return; + } + + if (!folderName.equals(myCurrentFolder.getName())) { + // if one of path components differs - no sense in checking others + myCurrentFolder = null; + return; + } + + // common folder was found, let's increase proximity degree and move to parent folder + myProximity ++; + myCurrentFolder = myCurrentFolder.getParent(); + } + + public VirtualFile getFile() { + return myFile; + } + + public int getProximity() { + return myProximity; + } + } } From 30255598bad6c2217f62014bb2a8a056d9360877 Mon Sep 17 00:00:00 2001 From: Roman Chernyatchik Date: Sat, 24 Oct 2009 15:12:44 +0400 Subject: [PATCH 4/5] code was uncommented --- .../execution/testframework/sm/TestsLocationProviderUtil.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/TestsLocationProviderUtil.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/TestsLocationProviderUtil.java index 4b589ddaf40b..ecaf0ae2dcfd 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/TestsLocationProviderUtil.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/TestsLocationProviderUtil.java @@ -75,8 +75,7 @@ public class TestsLocationProviderUtil { final boolean inProjectContent = file != null && (index.isInContent(file)); if (inProjectContent) { - // TODO - //return Collections.singletonList(file); + return Collections.singletonList(file); } //split file by "/" in parts From 49e4bc791c71bf39f171a063f4c4e3c3f5be66c0 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Sun, 25 Oct 2009 12:11:36 +0300 Subject: [PATCH 5/5] TreeUi: expand elements optimization --- .../ide/util/treeView/AbstractTreeUi.java | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java index c84a46b90cf4..297d34242879 100644 --- a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java +++ b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java @@ -2803,17 +2803,29 @@ public class AbstractTreeUi { } }); - for (final Object toExpand : element) { - _expand(toExpand, new Runnable() { - public void run() { - done.setDone(); - } - }, parentsOnly, checkIfInStructure, canSmartExpand); - } + expandNext(element, 0, parentsOnly, checkIfInStructure, canSmartExpand, done); } }); } + private void expandNext(final Object[] elements, final int index, final boolean parentsOnly, final boolean checkIfInStricture, final boolean canSmartExpand, final ActionCallback done) { + if (elements.length <= 0) { + done.setDone(); + return; + } + + if (index >= elements.length) { + return; + } + + _expand(elements[index], new Runnable() { + public void run() { + done.setDone(); + expandNext(elements, index + 1, parentsOnly, checkIfInStricture, canSmartExpand, done); + } + }, parentsOnly, checkIfInStricture, canSmartExpand); + } + public void collapseChildren(final Object element, @Nullable final Runnable onDone) { runDone(new Runnable() { public void run() {