diff --git a/plugins/stream-debugger/resources/META-INF/plugin.xml b/plugins/stream-debugger/resources/META-INF/plugin.xml
index 0d9da627d4cd..1de4a6e12e87 100644
--- a/plugins/stream-debugger/resources/META-INF/plugin.xml
+++ b/plugins/stream-debugger/resources/META-INF/plugin.xml
@@ -65,6 +65,7 @@
+
diff --git a/plugins/stream-debugger/src/com/intellij/debugger/streams/lib/impl/JBIterableSupport.kt b/plugins/stream-debugger/src/com/intellij/debugger/streams/lib/impl/JBIterableSupport.kt
new file mode 100644
index 000000000000..6294f1cba3a4
--- /dev/null
+++ b/plugins/stream-debugger/src/com/intellij/debugger/streams/lib/impl/JBIterableSupport.kt
@@ -0,0 +1,35 @@
+// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package com.intellij.debugger.streams.lib.impl
+
+import com.intellij.debugger.streams.resolve.AppendResolver
+import com.intellij.debugger.streams.trace.impl.handler.unified.DistinctByKeyHandler
+import com.intellij.debugger.streams.trace.impl.handler.unified.DistinctTraceHandler
+
+/**
+ * @author Vitaliy.Bibaev
+ */
+class JBIterableSupport : LibrarySupportBase() {
+ companion object {
+ fun filterOperations(vararg names: String): Array = names.map { FilterOperation(it) }.toTypedArray()
+ fun mapOperations(vararg names: String): Array = names.map { MappingOperation(it) }.toTypedArray()
+ }
+
+ init {
+ addIntermediateOperationsSupport(*filterOperations("filter", "skip", "skipWhile", "take", "takeWhile"))
+ addIntermediateOperationsSupport(*mapOperations("map", "transform"))
+ addIntermediateOperationsSupport(FlatMappingOperation("flatMap"),
+ FlatMappingOperation("flatten"))
+
+ addIntermediateOperationsSupport(DistinctOperation("unique") { num, call, dsl ->
+ val arguments = call.arguments
+ if (arguments.isEmpty()) {
+ return@DistinctOperation DistinctTraceHandler(num, call, dsl)
+ }
+ return@DistinctOperation DistinctByKeyHandler(num, call, dsl)
+ })
+
+ addIntermediateOperationsSupport(ConcatOperation("append", AppendResolver()))
+
+ addIntermediateOperationsSupport(SortedOperation("sorted"), SortedOperation("collect"))
+ }
+}
\ No newline at end of file
diff --git a/plugins/stream-debugger/src/com/intellij/debugger/streams/lib/impl/JBIterableSupportProvider.kt b/plugins/stream-debugger/src/com/intellij/debugger/streams/lib/impl/JBIterableSupportProvider.kt
new file mode 100644
index 000000000000..6a9bb07ff6cb
--- /dev/null
+++ b/plugins/stream-debugger/src/com/intellij/debugger/streams/lib/impl/JBIterableSupportProvider.kt
@@ -0,0 +1,71 @@
+// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package com.intellij.debugger.streams.lib.impl
+
+import com.intellij.debugger.streams.lib.LibrarySupport
+import com.intellij.debugger.streams.lib.LibrarySupportProvider
+import com.intellij.debugger.streams.psi.impl.InheritanceBasedChainDetector
+import com.intellij.debugger.streams.psi.impl.JavaChainTransformerImpl
+import com.intellij.debugger.streams.psi.impl.JavaStreamChainBuilder
+import com.intellij.debugger.streams.trace.TraceExpressionBuilder
+import com.intellij.debugger.streams.trace.dsl.Lambda
+import com.intellij.debugger.streams.trace.dsl.impl.DslImpl
+import com.intellij.debugger.streams.trace.dsl.impl.TextExpression
+import com.intellij.debugger.streams.trace.dsl.impl.java.JavaStatementFactory
+import com.intellij.debugger.streams.trace.impl.JavaTraceExpressionBuilder
+import com.intellij.debugger.streams.trace.impl.handler.type.GenericType
+import com.intellij.debugger.streams.wrapper.CallArgument
+import com.intellij.debugger.streams.wrapper.IntermediateStreamCall
+import com.intellij.debugger.streams.wrapper.StreamCallType
+import com.intellij.debugger.streams.wrapper.StreamChainBuilder
+import com.intellij.debugger.streams.wrapper.impl.CallArgumentImpl
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.util.TextRange
+import com.intellij.psi.CommonClassNames
+
+/**
+ * @author Vitaliy.Bibaev
+ */
+class JBIterableSupportProvider : LibrarySupportProvider {
+ private companion object {
+ const val CLASS_NAME = "com.intellij.util.containers.JBIterable"
+ }
+
+ private val librarySupport = JBIterableSupport()
+ private val dsl = DslImpl(JBIterableJavaStatementFactory())
+ override fun getLanguageId(): String = "JAVA"
+
+ override fun getChainBuilder(): StreamChainBuilder {
+ return JavaStreamChainBuilder(JavaChainTransformerImpl(), InheritanceBasedChainDetector(CLASS_NAME))
+ }
+
+ override fun getExpressionBuilder(project: Project): TraceExpressionBuilder {
+ return JavaTraceExpressionBuilder(project, librarySupport.createHandlerFactory(dsl), dsl)
+ }
+
+ override fun getLibrarySupport(): LibrarySupport = librarySupport
+
+ private class JBIterableJavaStatementFactory : JavaStatementFactory() {
+ override fun createPeekCall(elementsType: GenericType, lambda: Lambda): IntermediateStreamCall {
+ val lambdaBody = createEmptyLambdaBody(lambda.variableName).apply {
+ add(lambda.body)
+ doReturn(TextExpression("true"))
+ }
+ val newLambda = createLambda(lambda.variableName, lambdaBody)
+ return JBIterablePeekCall(elementsType, newLambda.toCode())
+ }
+ }
+
+ private class JBIterablePeekCall(private val elementsType: GenericType, private val argText: String) : IntermediateStreamCall {
+ override fun getName(): String = "filter"
+
+ override fun getArguments(): List = listOf(CallArgumentImpl(CommonClassNames.JAVA_LANG_OBJECT, argText))
+
+ override fun getType(): StreamCallType = StreamCallType.INTERMEDIATE
+
+ override fun getTextRange(): TextRange = TextRange.EMPTY_RANGE
+
+ override fun getTypeBefore(): GenericType = elementsType
+
+ override fun getTypeAfter(): GenericType = elementsType
+ }
+}
\ No newline at end of file
diff --git a/plugins/stream-debugger/src/com/intellij/debugger/streams/psi/impl/InheritanceBasedChainDetector.kt b/plugins/stream-debugger/src/com/intellij/debugger/streams/psi/impl/InheritanceBasedChainDetector.kt
new file mode 100644
index 000000000000..4317ebc0e912
--- /dev/null
+++ b/plugins/stream-debugger/src/com/intellij/debugger/streams/psi/impl/InheritanceBasedChainDetector.kt
@@ -0,0 +1,26 @@
+// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package com.intellij.debugger.streams.psi.impl
+
+import com.intellij.debugger.streams.psi.ChainDetector
+import com.intellij.psi.PsiClass
+import com.intellij.psi.PsiMethodCallExpression
+import com.intellij.psi.PsiType
+import com.intellij.psi.util.InheritanceUtil
+
+/**
+ * @author Vitaliy.Bibaev
+ */
+class InheritanceBasedChainDetector(private val baseClassName: String) : ChainDetector {
+ override fun isTerminationCall(callExpression: PsiMethodCallExpression): Boolean {
+ val method = callExpression.resolveMethod() ?: return false
+ return isStreamType(method.parent as? PsiClass) && !isStreamType(method.returnType)
+ }
+
+ override fun isIntermediateCall(callExpression: PsiMethodCallExpression): Boolean {
+ return isStreamType(callExpression.resolveMethod()?.returnType)
+ }
+
+ private fun isStreamType(type: PsiType?): Boolean = InheritanceUtil.isInheritor(type, baseClassName)
+
+ private fun isStreamType(type: PsiClass?): Boolean = InheritanceUtil.isInheritor(type, baseClassName)
+}
\ No newline at end of file