diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/NativeElementsFactory.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/NativeElementsFactory.kt
new file mode 100644
index 0000000..58a026a
--- /dev/null
+++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/NativeElementsFactory.kt
@@ -0,0 +1,16 @@
+/*
+ * 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/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.cli.jvm.compiler.tmp
+
+import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
+import org.jetbrains.kotlin.diagnostics.Diagnostic
+import org.jetbrains.kotlin.types.KotlinType
+
+interface NativeElementsFactory {
+    fun convertToRDumpDescriptor(descriptor: DeclarationDescriptor): RDumpDescriptor
+    fun convertToRDumpType(type: KotlinType): RDumpType
+    fun convertToRDumpDiagnostic(diagnostic: Diagnostic): RDumpDiagnostic
+}
diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/ResolutionDump.proto b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/ResolutionDump.proto
new file mode 100644
index 0000000..f4ea729
--- /dev/null
+++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/ResolutionDump.proto
@@ -0,0 +1,56 @@
+package org.jetbrains.kotlin.cli.jvm.compiler.tmp;
+
+option java_outer_classname = "ResolutionDumpProtoBuf";
+
+option optimize_for = LITE_RUNTIME;
+
+message ResolutionResultForFile {
+    optional File file = 1;
+    repeated Element element = 2;
+}
+
+message Element {
+    optional int32 offset = 1;
+    optional string presentable_text = 2;
+
+    // One-of:
+    optional Expression expression = 3;
+}
+
+message Expression {
+    optional Type type = 1;
+
+    // One-of:
+    optional Resolved resolved = 2;
+    optional Error error = 3;
+}
+
+message Resolved {
+    optional Descriptor candidate_descriptor = 1;
+    repeated Type type_argument = 2;
+}
+
+message Error {
+    repeated Diagnostic diagnostic = 1;
+}
+
+message Diagnostic {
+    // TODO: stub
+    optional string diagnostic_family = 1;
+    optional string rendered_text = 2;
+}
+
+message Descriptor {
+    // TODO: stub
+    optional string fqn = 1;
+    repeated Descriptor type_parameter = 2;
+}
+
+message Type {
+    // TODO: stub
+    optional string rendered_type = 1;
+}
+
+message File {
+    optional string relative_path = 1;
+}
\ No newline at end of file
diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/ResolutionDumpBuilder.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/ResolutionDumpBuilder.kt
new file mode 100644
index 0000000..67a9400
--- /dev/null
+++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/ResolutionDumpBuilder.kt
@@ -0,0 +1,79 @@
+/*
+ * 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/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.cli.jvm.compiler.tmp
+
+import org.jetbrains.kotlin.cli.jvm.compiler.tmp.impls.FileBasedRDumpFile
+import org.jetbrains.kotlin.cli.jvm.compiler.tmp.impls.RDumpResolvedCall
+import org.jetbrains.kotlin.ir.IrElement
+import org.jetbrains.kotlin.ir.declarations.IrDeclaration
+import org.jetbrains.kotlin.ir.declarations.IrFile
+import org.jetbrains.kotlin.ir.expressions.IrBody
+import org.jetbrains.kotlin.ir.expressions.IrCall
+import org.jetbrains.kotlin.ir.util.dump
+import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
+import org.jetbrains.kotlin.renderer.DescriptorRenderer
+import org.jetbrains.kotlin.resolve.BindingContext
+import org.jetbrains.kotlin.types.ErrorType
+import org.jetbrains.kotlin.types.ErrorUtils
+import org.jetbrains.kotlin.types.KotlinType
+import java.io.File
+
+class IrBasedResolutionDumpBuilder(
+    private val bindingContext: BindingContext,
+    private val nativeElementsFactory: NativeElementsFactory,
+    private val root: File
+) {
+    fun buildResolutionDumpForFile(irFile: IrFile, correspondingPhysicalFile: File): RDumpForFile {
+        val results = Ir2ResolutionDumpConverter().collectResolutionResultsFromSubtree(irFile)
+        return RDumpForFile(
+            FileBasedRDumpFile(correspondingPhysicalFile, correspondingPhysicalFile.toRelativeString(root)),
+            results
+        )
+    }
+
+    inner class Ir2ResolutionDumpConverter : IrElementVisitorVoid {
+        private val results: MutableList<RDumpElement> = mutableListOf()
+
+        fun collectResolutionResultsFromSubtree(irElement: IrElement): List<RDumpElement> {
+            irElement.accept(this, null)
+            return results
+        }
+
+
+        // === Visitor ===
+
+        override fun visitElement(element: IrElement) {
+            throw IllegalStateException("Shouldn't visit $element")
+        }
+
+        override fun visitDeclaration(declaration: IrDeclaration) {
+            declaration.acceptChildren(this, null)
+        }
+
+        override fun visitBody(body: IrBody) {
+            body.acceptChildren(this, null)
+        }
+
+        // Expressions
+        override fun visitCall(expression: IrCall) {
+            val descriptor = expression.descriptor
+            val rDumpDescriptor = nativeElementsFactory.convertToRDumpDescriptor(descriptor)
+            val rDumpType = nativeElementsFactory.convertToRDumpType(expression.type)
+
+            val typeArguments: MutableList<RDumpType> = mutableListOf()
+            for ((i, typeParameter) in descriptor.typeParameters.withIndex()) {
+                val kotlinTypeArgument = expression.getTypeArgument(i)
+                        ?: ErrorUtils.createErrorType("Error type for typeParameter ${DescriptorRenderer.COMPACT.render(typeParameter)}")
+                typeArguments.add(nativeElementsFactory.convertToRDumpType(kotlinTypeArgument))
+            }
+
+            results.add(RDumpResolvedCall(expression.startOffset, expression.dump(), rDumpType, rDumpDescriptor, typeArguments))
+        }
+    }
+
+    inner class AdditionalDiagnosticInfoProvider {
+    }
+}
\ No newline at end of file
diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/ResolutionDumpDeserializer.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/ResolutionDumpDeserializer.kt
new file mode 100644
index 0000000..50af354
--- /dev/null
+++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/ResolutionDumpDeserializer.kt
@@ -0,0 +1,88 @@
+/*
+ * 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/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.cli.jvm.compiler.tmp
+
+import org.jetbrains.kotlin.cli.jvm.compiler.tmp.impls.*
+import java.io.File
+
+interface ResolutionDumpDeserializer {
+    fun deserializeResolutionResults(bytes: ByteArray): RDumpForFile
+}
+
+class ProtoBufResolutionDumpDeserializer(private val root: File) : ResolutionDumpDeserializer {
+    override fun deserializeResolutionResults(bytes: ByteArray): RDumpForFile {
+        val proto: ResolutionDumpProtoBuf.ResolutionResultForFile = ResolutionDumpProtoBuf.ResolutionResultForFile.parseFrom(bytes)
+
+        return loadDumpForFile(proto)
+    }
+
+    private fun loadDumpForFile(dumpForFileProto: ResolutionDumpProtoBuf.ResolutionResultForFile): RDumpForFile {
+        val file = loadFile(dumpForFileProto.file)
+
+        val elements = dumpForFileProto.elementList.map { loadElement(it) }
+        return RDumpForFile(file, elements)
+    }
+
+    private fun loadElement(elementProto: ResolutionDumpProtoBuf.Element): RDumpElement {
+        val offset = elementProto.offset
+        val presentableText = elementProto.presentableText
+
+        return when {
+            elementProto.hasExpression() -> loadExpression(offset, presentableText, elementProto.expression)
+            else -> throw IllegalStateException("Unknown deserialized resolution dump element") // TODO: do we need better error handling here?
+        }
+    }
+
+    private fun loadExpression(offset: Int, presentableText: String, expressionProto: ResolutionDumpProtoBuf.Expression): RDumpExpression {
+        val type = loadType(expressionProto.type)
+
+        return when {
+            expressionProto.hasError() -> loadError(offset, presentableText, expressionProto.error)
+            expressionProto.hasResolved() -> loadResolved(offset, presentableText, type, expressionProto.resolved)
+            else -> throw IllegalStateException("Unknown deserialized resolution dump element") // TODO: do we need better error handling here?
+        }
+    }
+
+    private fun loadResolved(
+        offset: Int,
+        presentableText: String,
+        type: RDumpType,
+        resolvedProto: ResolutionDumpProtoBuf.Resolved
+    ): RDumpExpression {
+        val typeArguments = resolvedProto.typeArgumentList.map { loadType(it) }
+        val descriptor = loadDescriptor(resolvedProto.candidateDescriptor)
+
+        return RDumpResolvedCall(offset, presentableText, type, descriptor, typeArguments)
+    }
+
+    private fun loadDescriptor(descriptorProto: ResolutionDumpProtoBuf.Descriptor): RDumpDescriptor =
+        TextBasedRDumpDescriptor(
+            descriptorProto.fqn,
+            descriptorProto.typeParameterList.map { loadDescriptor(it) }
+        )
+
+    private fun loadError(offset: Int, presentableText: String, errorProto: ResolutionDumpProtoBuf.Error): RDumpErrorCall {
+        val diagnostics = errorProto.diagnosticList.map { loadDiagnostic(it) }
+        return RDumpErrorCall(offset, presentableText, diagnostics)
+    }
+
+    private fun loadDiagnostic(diagnosticProto: ResolutionDumpProtoBuf.Diagnostic): RDumpDiagnostic {
+        return TextBasedRDumpDiagnostic(diagnosticProto.diagnosticFamily, diagnosticProto.renderedText)
+    }
+
+    private fun loadType(type: ResolutionDumpProtoBuf.Type): RDumpType {
+        return TextBasedRDumpType(type.renderedType)
+    }
+
+    private fun loadFile(fileProto: ResolutionDumpProtoBuf.File): RDumpFile {
+        val file = File(root, fileProto.relativePath)
+        if (!file.exists()) {
+            throw IllegalStateException("Deserialized File with relative path ${fileProto.relativePath} hasn't been resolved relative to root=$root")
+        }
+
+        return FileBasedRDumpFile(file, fileProto.relativePath)
+    }
+}
\ No newline at end of file
diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/ResolutionDumpProtoBuf.java b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/ResolutionDumpProtoBuf.java
new file mode 100644
index 0000000..845981c
--- /dev/null
+++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/ResolutionDumpProtoBuf.java
@@ -0,0 +1,5247 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: org/jetbrains/kotlin/cli/jvm/compiler/tmp/ResolutionDump.proto
+
+package org.jetbrains.kotlin.cli.jvm.compiler.tmp;
+
+public final class ResolutionDumpProtoBuf {
+  private ResolutionDumpProtoBuf() {}
+  public static void registerAllExtensions(
+      org.jetbrains.kotlin.protobuf.ExtensionRegistryLite registry) {
+  }
+  public interface ResolutionResultForFileOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionResultForFile)
+      org.jetbrains.kotlin.protobuf.MessageLiteOrBuilder {
+
+    /**
+     * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.File file = 1;</code>
+     */
+    boolean hasFile();
+    /**
+     * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.File file = 1;</code>
+     */
+    org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File getFile();
+
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element element = 2;</code>
+     */
+    java.util.List<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element> 
+        getElementList();
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element element = 2;</code>
+     */
+    org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element getElement(int index);
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element element = 2;</code>
+     */
+    int getElementCount();
+  }
+  /**
+   * Protobuf type {@code org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionResultForFile}
+   */
+  public static final class ResolutionResultForFile extends
+      org.jetbrains.kotlin.protobuf.GeneratedMessageLite implements
+      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionResultForFile)
+      ResolutionResultForFileOrBuilder {
+    // Use ResolutionResultForFile.newBuilder() to construct.
+    private ResolutionResultForFile(org.jetbrains.kotlin.protobuf.GeneratedMessageLite.Builder builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private ResolutionResultForFile(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.ByteString.EMPTY;}
+
+    private static final ResolutionResultForFile defaultInstance;
+    public static ResolutionResultForFile getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public ResolutionResultForFile getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final org.jetbrains.kotlin.protobuf.ByteString unknownFields;
+    private ResolutionResultForFile(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      org.jetbrains.kotlin.protobuf.ByteString.Output unknownFieldsOutput =
+          org.jetbrains.kotlin.protobuf.ByteString.newOutput();
+      org.jetbrains.kotlin.protobuf.CodedOutputStream unknownFieldsCodedOutput =
+          org.jetbrains.kotlin.protobuf.CodedOutputStream.newInstance(
+              unknownFieldsOutput);
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFieldsCodedOutput,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+                subBuilder = file_.toBuilder();
+              }
+              file_ = input.readMessage(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(file_);
+                file_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000001;
+              break;
+            }
+            case 18: {
+              if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+                element_ = new java.util.ArrayList<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element>();
+                mutable_bitField0_ |= 0x00000002;
+              }
+              element_.add(input.readMessage(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element.PARSER, extensionRegistry));
+              break;
+            }
+          }
+        }
+      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+          element_ = java.util.Collections.unmodifiableList(element_);
+        }
+        try {
+          unknownFieldsCodedOutput.flush();
+        } catch (java.io.IOException e) {
+        // Should not happen
+        } finally {
+          unknownFields = unknownFieldsOutput.toByteString();
+        }
+        makeExtensionsImmutable();
+      }
+    }
+    public static org.jetbrains.kotlin.protobuf.Parser<ResolutionResultForFile> PARSER =
+        new org.jetbrains.kotlin.protobuf.AbstractParser<ResolutionResultForFile>() {
+      public ResolutionResultForFile parsePartialFrom(
+          org.jetbrains.kotlin.protobuf.CodedInputStream input,
+          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+        return new ResolutionResultForFile(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public org.jetbrains.kotlin.protobuf.Parser<ResolutionResultForFile> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    public static final int FILE_FIELD_NUMBER = 1;
+    private org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File file_;
+    /**
+     * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.File file = 1;</code>
+     */
+    public boolean hasFile() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.File file = 1;</code>
+     */
+    public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File getFile() {
+      return file_;
+    }
+
+    public static final int ELEMENT_FIELD_NUMBER = 2;
+    private java.util.List<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element> element_;
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element element = 2;</code>
+     */
+    public java.util.List<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element> getElementList() {
+      return element_;
+    }
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element element = 2;</code>
+     */
+    public java.util.List<? extends org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ElementOrBuilder> 
+        getElementOrBuilderList() {
+      return element_;
+    }
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element element = 2;</code>
+     */
+    public int getElementCount() {
+      return element_.size();
+    }
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element element = 2;</code>
+     */
+    public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element getElement(int index) {
+      return element_.get(index);
+    }
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element element = 2;</code>
+     */
+    public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ElementOrBuilder getElementOrBuilder(
+        int index) {
+      return element_.get(index);
+    }
+
+    private void initFields() {
+      file_ = org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File.getDefaultInstance();
+      element_ = java.util.Collections.emptyList();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeMessage(1, file_);
+      }
+      for (int i = 0; i < element_.size(); i++) {
+        output.writeMessage(2, element_.get(i));
+      }
+      output.writeRawBytes(unknownFields);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
+          .computeMessageSize(1, file_);
+      }
+      for (int i = 0; i < element_.size(); i++) {
+        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
+          .computeMessageSize(2, element_.get(i));
+      }
+      size += unknownFields.size();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ResolutionResultForFile parseFrom(
+        org.jetbrains.kotlin.protobuf.ByteString data)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ResolutionResultForFile parseFrom(
+        org.jetbrains.kotlin.protobuf.ByteString data,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ResolutionResultForFile parseFrom(byte[] data)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ResolutionResultForFile parseFrom(
+        byte[] data,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ResolutionResultForFile parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ResolutionResultForFile parseFrom(
+        java.io.InputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ResolutionResultForFile parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ResolutionResultForFile parseDelimitedFrom(
+        java.io.InputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ResolutionResultForFile parseFrom(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ResolutionResultForFile parseFrom(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ResolutionResultForFile prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    /**
+     * Protobuf type {@code org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionResultForFile}
+     */
+    public static final class Builder extends
+        org.jetbrains.kotlin.protobuf.GeneratedMessageLite.Builder<
+          org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ResolutionResultForFile, Builder>
+        implements
+        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionResultForFile)
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ResolutionResultForFileOrBuilder {
+      // Construct using org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ResolutionResultForFile.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private void maybeForceBuilderInitialization() {
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        file_ = org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File.getDefaultInstance();
+        bitField0_ = (bitField0_ & ~0x00000001);
+        element_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000002);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ResolutionResultForFile getDefaultInstanceForType() {
+        return org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ResolutionResultForFile.getDefaultInstance();
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ResolutionResultForFile build() {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ResolutionResultForFile result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ResolutionResultForFile buildPartial() {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ResolutionResultForFile result = new org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ResolutionResultForFile(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.file_ = file_;
+        if (((bitField0_ & 0x00000002) == 0x00000002)) {
+          element_ = java.util.Collections.unmodifiableList(element_);
+          bitField0_ = (bitField0_ & ~0x00000002);
+        }
+        result.element_ = element_;
+        result.bitField0_ = to_bitField0_;
+        return result;
+      }
+
+      public Builder mergeFrom(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ResolutionResultForFile other) {
+        if (other == org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ResolutionResultForFile.getDefaultInstance()) return this;
+        if (other.hasFile()) {
+          mergeFile(other.getFile());
+        }
+        if (!other.element_.isEmpty()) {
+          if (element_.isEmpty()) {
+            element_ = other.element_;
+            bitField0_ = (bitField0_ & ~0x00000002);
+          } else {
+            ensureElementIsMutable();
+            element_.addAll(other.element_);
+          }
+          
+        }
+        setUnknownFields(
+            getUnknownFields().concat(other.unknownFields));
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          org.jetbrains.kotlin.protobuf.CodedInputStream input,
+          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ResolutionResultForFile parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ResolutionResultForFile) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      private org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File file_ = org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File.getDefaultInstance();
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.File file = 1;</code>
+       */
+      public boolean hasFile() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.File file = 1;</code>
+       */
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File getFile() {
+        return file_;
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.File file = 1;</code>
+       */
+      public Builder setFile(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        file_ = value;
+
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.File file = 1;</code>
+       */
+      public Builder setFile(
+          org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File.Builder builderForValue) {
+        file_ = builderForValue.build();
+
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.File file = 1;</code>
+       */
+      public Builder mergeFile(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File value) {
+        if (((bitField0_ & 0x00000001) == 0x00000001) &&
+            file_ != org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File.getDefaultInstance()) {
+          file_ =
+            org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File.newBuilder(file_).mergeFrom(value).buildPartial();
+        } else {
+          file_ = value;
+        }
+
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.File file = 1;</code>
+       */
+      public Builder clearFile() {
+        file_ = org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File.getDefaultInstance();
+
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+
+      private java.util.List<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element> element_ =
+        java.util.Collections.emptyList();
+      private void ensureElementIsMutable() {
+        if (!((bitField0_ & 0x00000002) == 0x00000002)) {
+          element_ = new java.util.ArrayList<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element>(element_);
+          bitField0_ |= 0x00000002;
+         }
+      }
+
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element element = 2;</code>
+       */
+      public java.util.List<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element> getElementList() {
+        return java.util.Collections.unmodifiableList(element_);
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element element = 2;</code>
+       */
+      public int getElementCount() {
+        return element_.size();
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element element = 2;</code>
+       */
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element getElement(int index) {
+        return element_.get(index);
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element element = 2;</code>
+       */
+      public Builder setElement(
+          int index, org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureElementIsMutable();
+        element_.set(index, value);
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element element = 2;</code>
+       */
+      public Builder setElement(
+          int index, org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element.Builder builderForValue) {
+        ensureElementIsMutable();
+        element_.set(index, builderForValue.build());
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element element = 2;</code>
+       */
+      public Builder addElement(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureElementIsMutable();
+        element_.add(value);
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element element = 2;</code>
+       */
+      public Builder addElement(
+          int index, org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureElementIsMutable();
+        element_.add(index, value);
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element element = 2;</code>
+       */
+      public Builder addElement(
+          org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element.Builder builderForValue) {
+        ensureElementIsMutable();
+        element_.add(builderForValue.build());
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element element = 2;</code>
+       */
+      public Builder addElement(
+          int index, org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element.Builder builderForValue) {
+        ensureElementIsMutable();
+        element_.add(index, builderForValue.build());
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element element = 2;</code>
+       */
+      public Builder addAllElement(
+          java.lang.Iterable<? extends org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element> values) {
+        ensureElementIsMutable();
+        org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll(
+            values, element_);
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element element = 2;</code>
+       */
+      public Builder clearElement() {
+        element_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000002);
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element element = 2;</code>
+       */
+      public Builder removeElement(int index) {
+        ensureElementIsMutable();
+        element_.remove(index);
+
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionResultForFile)
+    }
+
+    static {
+      defaultInstance = new ResolutionResultForFile(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionResultForFile)
+  }
+
+  public interface ElementOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element)
+      org.jetbrains.kotlin.protobuf.MessageLiteOrBuilder {
+
+    /**
+     * <code>optional int32 offset = 1;</code>
+     */
+    boolean hasOffset();
+    /**
+     * <code>optional int32 offset = 1;</code>
+     */
+    int getOffset();
+
+    /**
+     * <code>optional string presentable_text = 2;</code>
+     */
+    boolean hasPresentableText();
+    /**
+     * <code>optional string presentable_text = 2;</code>
+     */
+    java.lang.String getPresentableText();
+    /**
+     * <code>optional string presentable_text = 2;</code>
+     */
+    org.jetbrains.kotlin.protobuf.ByteString
+        getPresentableTextBytes();
+
+    /**
+     * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Expression expression = 3;</code>
+     *
+     * <pre>
+     * One-of:
+     * </pre>
+     */
+    boolean hasExpression();
+    /**
+     * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Expression expression = 3;</code>
+     *
+     * <pre>
+     * One-of:
+     * </pre>
+     */
+    org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression getExpression();
+  }
+  /**
+   * Protobuf type {@code org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element}
+   */
+  public static final class Element extends
+      org.jetbrains.kotlin.protobuf.GeneratedMessageLite implements
+      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element)
+      ElementOrBuilder {
+    // Use Element.newBuilder() to construct.
+    private Element(org.jetbrains.kotlin.protobuf.GeneratedMessageLite.Builder builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private Element(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.ByteString.EMPTY;}
+
+    private static final Element defaultInstance;
+    public static Element getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public Element getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final org.jetbrains.kotlin.protobuf.ByteString unknownFields;
+    private Element(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      org.jetbrains.kotlin.protobuf.ByteString.Output unknownFieldsOutput =
+          org.jetbrains.kotlin.protobuf.ByteString.newOutput();
+      org.jetbrains.kotlin.protobuf.CodedOutputStream unknownFieldsCodedOutput =
+          org.jetbrains.kotlin.protobuf.CodedOutputStream.newInstance(
+              unknownFieldsOutput);
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFieldsCodedOutput,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 8: {
+              bitField0_ |= 0x00000001;
+              offset_ = input.readInt32();
+              break;
+            }
+            case 18: {
+              org.jetbrains.kotlin.protobuf.ByteString bs = input.readBytes();
+              bitField0_ |= 0x00000002;
+              presentableText_ = bs;
+              break;
+            }
+            case 26: {
+              org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000004) == 0x00000004)) {
+                subBuilder = expression_.toBuilder();
+              }
+              expression_ = input.readMessage(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(expression_);
+                expression_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000004;
+              break;
+            }
+          }
+        }
+      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        try {
+          unknownFieldsCodedOutput.flush();
+        } catch (java.io.IOException e) {
+        // Should not happen
+        } finally {
+          unknownFields = unknownFieldsOutput.toByteString();
+        }
+        makeExtensionsImmutable();
+      }
+    }
+    public static org.jetbrains.kotlin.protobuf.Parser<Element> PARSER =
+        new org.jetbrains.kotlin.protobuf.AbstractParser<Element>() {
+      public Element parsePartialFrom(
+          org.jetbrains.kotlin.protobuf.CodedInputStream input,
+          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+        return new Element(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public org.jetbrains.kotlin.protobuf.Parser<Element> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    public static final int OFFSET_FIELD_NUMBER = 1;
+    private int offset_;
+    /**
+     * <code>optional int32 offset = 1;</code>
+     */
+    public boolean hasOffset() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>optional int32 offset = 1;</code>
+     */
+    public int getOffset() {
+      return offset_;
+    }
+
+    public static final int PRESENTABLE_TEXT_FIELD_NUMBER = 2;
+    private java.lang.Object presentableText_;
+    /**
+     * <code>optional string presentable_text = 2;</code>
+     */
+    public boolean hasPresentableText() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>optional string presentable_text = 2;</code>
+     */
+    public java.lang.String getPresentableText() {
+      java.lang.Object ref = presentableText_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        org.jetbrains.kotlin.protobuf.ByteString bs = 
+            (org.jetbrains.kotlin.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          presentableText_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>optional string presentable_text = 2;</code>
+     */
+    public org.jetbrains.kotlin.protobuf.ByteString
+        getPresentableTextBytes() {
+      java.lang.Object ref = presentableText_;
+      if (ref instanceof java.lang.String) {
+        org.jetbrains.kotlin.protobuf.ByteString b = 
+            org.jetbrains.kotlin.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        presentableText_ = b;
+        return b;
+      } else {
+        return (org.jetbrains.kotlin.protobuf.ByteString) ref;
+      }
+    }
+
+    public static final int EXPRESSION_FIELD_NUMBER = 3;
+    private org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression expression_;
+    /**
+     * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Expression expression = 3;</code>
+     *
+     * <pre>
+     * One-of:
+     * </pre>
+     */
+    public boolean hasExpression() {
+      return ((bitField0_ & 0x00000004) == 0x00000004);
+    }
+    /**
+     * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Expression expression = 3;</code>
+     *
+     * <pre>
+     * One-of:
+     * </pre>
+     */
+    public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression getExpression() {
+      return expression_;
+    }
+
+    private void initFields() {
+      offset_ = 0;
+      presentableText_ = "";
+      expression_ = org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression.getDefaultInstance();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeInt32(1, offset_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeBytes(2, getPresentableTextBytes());
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        output.writeMessage(3, expression_);
+      }
+      output.writeRawBytes(unknownFields);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
+          .computeInt32Size(1, offset_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
+          .computeBytesSize(2, getPresentableTextBytes());
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
+          .computeMessageSize(3, expression_);
+      }
+      size += unknownFields.size();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element parseFrom(
+        org.jetbrains.kotlin.protobuf.ByteString data)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element parseFrom(
+        org.jetbrains.kotlin.protobuf.ByteString data,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element parseFrom(byte[] data)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element parseFrom(
+        byte[] data,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element parseFrom(
+        java.io.InputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element parseDelimitedFrom(
+        java.io.InputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element parseFrom(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element parseFrom(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    /**
+     * Protobuf type {@code org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element}
+     */
+    public static final class Builder extends
+        org.jetbrains.kotlin.protobuf.GeneratedMessageLite.Builder<
+          org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element, Builder>
+        implements
+        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element)
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ElementOrBuilder {
+      // Construct using org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private void maybeForceBuilderInitialization() {
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        offset_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000001);
+        presentableText_ = "";
+        bitField0_ = (bitField0_ & ~0x00000002);
+        expression_ = org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression.getDefaultInstance();
+        bitField0_ = (bitField0_ & ~0x00000004);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element getDefaultInstanceForType() {
+        return org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element.getDefaultInstance();
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element build() {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element buildPartial() {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element result = new org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.offset_ = offset_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.presentableText_ = presentableText_;
+        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+          to_bitField0_ |= 0x00000004;
+        }
+        result.expression_ = expression_;
+        result.bitField0_ = to_bitField0_;
+        return result;
+      }
+
+      public Builder mergeFrom(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element other) {
+        if (other == org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element.getDefaultInstance()) return this;
+        if (other.hasOffset()) {
+          setOffset(other.getOffset());
+        }
+        if (other.hasPresentableText()) {
+          bitField0_ |= 0x00000002;
+          presentableText_ = other.presentableText_;
+          
+        }
+        if (other.hasExpression()) {
+          mergeExpression(other.getExpression());
+        }
+        setUnknownFields(
+            getUnknownFields().concat(other.unknownFields));
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          org.jetbrains.kotlin.protobuf.CodedInputStream input,
+          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Element) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      private int offset_ ;
+      /**
+       * <code>optional int32 offset = 1;</code>
+       */
+      public boolean hasOffset() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>optional int32 offset = 1;</code>
+       */
+      public int getOffset() {
+        return offset_;
+      }
+      /**
+       * <code>optional int32 offset = 1;</code>
+       */
+      public Builder setOffset(int value) {
+        bitField0_ |= 0x00000001;
+        offset_ = value;
+        
+        return this;
+      }
+      /**
+       * <code>optional int32 offset = 1;</code>
+       */
+      public Builder clearOffset() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        offset_ = 0;
+        
+        return this;
+      }
+
+      private java.lang.Object presentableText_ = "";
+      /**
+       * <code>optional string presentable_text = 2;</code>
+       */
+      public boolean hasPresentableText() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>optional string presentable_text = 2;</code>
+       */
+      public java.lang.String getPresentableText() {
+        java.lang.Object ref = presentableText_;
+        if (!(ref instanceof java.lang.String)) {
+          org.jetbrains.kotlin.protobuf.ByteString bs =
+              (org.jetbrains.kotlin.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          if (bs.isValidUtf8()) {
+            presentableText_ = s;
+          }
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string presentable_text = 2;</code>
+       */
+      public org.jetbrains.kotlin.protobuf.ByteString
+          getPresentableTextBytes() {
+        java.lang.Object ref = presentableText_;
+        if (ref instanceof String) {
+          org.jetbrains.kotlin.protobuf.ByteString b = 
+              org.jetbrains.kotlin.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          presentableText_ = b;
+          return b;
+        } else {
+          return (org.jetbrains.kotlin.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string presentable_text = 2;</code>
+       */
+      public Builder setPresentableText(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        presentableText_ = value;
+        
+        return this;
+      }
+      /**
+       * <code>optional string presentable_text = 2;</code>
+       */
+      public Builder clearPresentableText() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        presentableText_ = getDefaultInstance().getPresentableText();
+        
+        return this;
+      }
+      /**
+       * <code>optional string presentable_text = 2;</code>
+       */
+      public Builder setPresentableTextBytes(
+          org.jetbrains.kotlin.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        presentableText_ = value;
+        
+        return this;
+      }
+
+      private org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression expression_ = org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression.getDefaultInstance();
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Expression expression = 3;</code>
+       *
+       * <pre>
+       * One-of:
+       * </pre>
+       */
+      public boolean hasExpression() {
+        return ((bitField0_ & 0x00000004) == 0x00000004);
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Expression expression = 3;</code>
+       *
+       * <pre>
+       * One-of:
+       * </pre>
+       */
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression getExpression() {
+        return expression_;
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Expression expression = 3;</code>
+       *
+       * <pre>
+       * One-of:
+       * </pre>
+       */
+      public Builder setExpression(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        expression_ = value;
+
+        bitField0_ |= 0x00000004;
+        return this;
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Expression expression = 3;</code>
+       *
+       * <pre>
+       * One-of:
+       * </pre>
+       */
+      public Builder setExpression(
+          org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression.Builder builderForValue) {
+        expression_ = builderForValue.build();
+
+        bitField0_ |= 0x00000004;
+        return this;
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Expression expression = 3;</code>
+       *
+       * <pre>
+       * One-of:
+       * </pre>
+       */
+      public Builder mergeExpression(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression value) {
+        if (((bitField0_ & 0x00000004) == 0x00000004) &&
+            expression_ != org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression.getDefaultInstance()) {
+          expression_ =
+            org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression.newBuilder(expression_).mergeFrom(value).buildPartial();
+        } else {
+          expression_ = value;
+        }
+
+        bitField0_ |= 0x00000004;
+        return this;
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Expression expression = 3;</code>
+       *
+       * <pre>
+       * One-of:
+       * </pre>
+       */
+      public Builder clearExpression() {
+        expression_ = org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression.getDefaultInstance();
+
+        bitField0_ = (bitField0_ & ~0x00000004);
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element)
+    }
+
+    static {
+      defaultInstance = new Element(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Element)
+  }
+
+  public interface ExpressionOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Expression)
+      org.jetbrains.kotlin.protobuf.MessageLiteOrBuilder {
+
+    /**
+     * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type = 1;</code>
+     */
+    boolean hasType();
+    /**
+     * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type = 1;</code>
+     */
+    org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type getType();
+
+    /**
+     * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Resolved resolved = 2;</code>
+     *
+     * <pre>
+     * One-of:
+     * </pre>
+     */
+    boolean hasResolved();
+    /**
+     * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Resolved resolved = 2;</code>
+     *
+     * <pre>
+     * One-of:
+     * </pre>
+     */
+    org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved getResolved();
+
+    /**
+     * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Error error = 3;</code>
+     */
+    boolean hasError();
+    /**
+     * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Error error = 3;</code>
+     */
+    org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error getError();
+  }
+  /**
+   * Protobuf type {@code org.jetbrains.kotlin.cli.jvm.compiler.tmp.Expression}
+   */
+  public static final class Expression extends
+      org.jetbrains.kotlin.protobuf.GeneratedMessageLite implements
+      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Expression)
+      ExpressionOrBuilder {
+    // Use Expression.newBuilder() to construct.
+    private Expression(org.jetbrains.kotlin.protobuf.GeneratedMessageLite.Builder builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private Expression(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.ByteString.EMPTY;}
+
+    private static final Expression defaultInstance;
+    public static Expression getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public Expression getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final org.jetbrains.kotlin.protobuf.ByteString unknownFields;
+    private Expression(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      org.jetbrains.kotlin.protobuf.ByteString.Output unknownFieldsOutput =
+          org.jetbrains.kotlin.protobuf.ByteString.newOutput();
+      org.jetbrains.kotlin.protobuf.CodedOutputStream unknownFieldsCodedOutput =
+          org.jetbrains.kotlin.protobuf.CodedOutputStream.newInstance(
+              unknownFieldsOutput);
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFieldsCodedOutput,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+                subBuilder = type_.toBuilder();
+              }
+              type_ = input.readMessage(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(type_);
+                type_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000001;
+              break;
+            }
+            case 18: {
+              org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+                subBuilder = resolved_.toBuilder();
+              }
+              resolved_ = input.readMessage(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(resolved_);
+                resolved_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000002;
+              break;
+            }
+            case 26: {
+              org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000004) == 0x00000004)) {
+                subBuilder = error_.toBuilder();
+              }
+              error_ = input.readMessage(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(error_);
+                error_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000004;
+              break;
+            }
+          }
+        }
+      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        try {
+          unknownFieldsCodedOutput.flush();
+        } catch (java.io.IOException e) {
+        // Should not happen
+        } finally {
+          unknownFields = unknownFieldsOutput.toByteString();
+        }
+        makeExtensionsImmutable();
+      }
+    }
+    public static org.jetbrains.kotlin.protobuf.Parser<Expression> PARSER =
+        new org.jetbrains.kotlin.protobuf.AbstractParser<Expression>() {
+      public Expression parsePartialFrom(
+          org.jetbrains.kotlin.protobuf.CodedInputStream input,
+          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+        return new Expression(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public org.jetbrains.kotlin.protobuf.Parser<Expression> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    public static final int TYPE_FIELD_NUMBER = 1;
+    private org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type type_;
+    /**
+     * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type = 1;</code>
+     */
+    public boolean hasType() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type = 1;</code>
+     */
+    public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type getType() {
+      return type_;
+    }
+
+    public static final int RESOLVED_FIELD_NUMBER = 2;
+    private org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved resolved_;
+    /**
+     * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Resolved resolved = 2;</code>
+     *
+     * <pre>
+     * One-of:
+     * </pre>
+     */
+    public boolean hasResolved() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Resolved resolved = 2;</code>
+     *
+     * <pre>
+     * One-of:
+     * </pre>
+     */
+    public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved getResolved() {
+      return resolved_;
+    }
+
+    public static final int ERROR_FIELD_NUMBER = 3;
+    private org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error error_;
+    /**
+     * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Error error = 3;</code>
+     */
+    public boolean hasError() {
+      return ((bitField0_ & 0x00000004) == 0x00000004);
+    }
+    /**
+     * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Error error = 3;</code>
+     */
+    public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error getError() {
+      return error_;
+    }
+
+    private void initFields() {
+      type_ = org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type.getDefaultInstance();
+      resolved_ = org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved.getDefaultInstance();
+      error_ = org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error.getDefaultInstance();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeMessage(1, type_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeMessage(2, resolved_);
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        output.writeMessage(3, error_);
+      }
+      output.writeRawBytes(unknownFields);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
+          .computeMessageSize(1, type_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
+          .computeMessageSize(2, resolved_);
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
+          .computeMessageSize(3, error_);
+      }
+      size += unknownFields.size();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression parseFrom(
+        org.jetbrains.kotlin.protobuf.ByteString data)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression parseFrom(
+        org.jetbrains.kotlin.protobuf.ByteString data,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression parseFrom(byte[] data)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression parseFrom(
+        byte[] data,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression parseFrom(
+        java.io.InputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression parseDelimitedFrom(
+        java.io.InputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression parseFrom(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression parseFrom(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    /**
+     * Protobuf type {@code org.jetbrains.kotlin.cli.jvm.compiler.tmp.Expression}
+     */
+    public static final class Builder extends
+        org.jetbrains.kotlin.protobuf.GeneratedMessageLite.Builder<
+          org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression, Builder>
+        implements
+        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Expression)
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ExpressionOrBuilder {
+      // Construct using org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private void maybeForceBuilderInitialization() {
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        type_ = org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type.getDefaultInstance();
+        bitField0_ = (bitField0_ & ~0x00000001);
+        resolved_ = org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved.getDefaultInstance();
+        bitField0_ = (bitField0_ & ~0x00000002);
+        error_ = org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error.getDefaultInstance();
+        bitField0_ = (bitField0_ & ~0x00000004);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression getDefaultInstanceForType() {
+        return org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression.getDefaultInstance();
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression build() {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression buildPartial() {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression result = new org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.type_ = type_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.resolved_ = resolved_;
+        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+          to_bitField0_ |= 0x00000004;
+        }
+        result.error_ = error_;
+        result.bitField0_ = to_bitField0_;
+        return result;
+      }
+
+      public Builder mergeFrom(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression other) {
+        if (other == org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression.getDefaultInstance()) return this;
+        if (other.hasType()) {
+          mergeType(other.getType());
+        }
+        if (other.hasResolved()) {
+          mergeResolved(other.getResolved());
+        }
+        if (other.hasError()) {
+          mergeError(other.getError());
+        }
+        setUnknownFields(
+            getUnknownFields().concat(other.unknownFields));
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          org.jetbrains.kotlin.protobuf.CodedInputStream input,
+          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Expression) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      private org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type type_ = org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type.getDefaultInstance();
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type = 1;</code>
+       */
+      public boolean hasType() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type = 1;</code>
+       */
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type getType() {
+        return type_;
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type = 1;</code>
+       */
+      public Builder setType(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        type_ = value;
+
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type = 1;</code>
+       */
+      public Builder setType(
+          org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type.Builder builderForValue) {
+        type_ = builderForValue.build();
+
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type = 1;</code>
+       */
+      public Builder mergeType(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type value) {
+        if (((bitField0_ & 0x00000001) == 0x00000001) &&
+            type_ != org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type.getDefaultInstance()) {
+          type_ =
+            org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type.newBuilder(type_).mergeFrom(value).buildPartial();
+        } else {
+          type_ = value;
+        }
+
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type = 1;</code>
+       */
+      public Builder clearType() {
+        type_ = org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type.getDefaultInstance();
+
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+
+      private org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved resolved_ = org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved.getDefaultInstance();
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Resolved resolved = 2;</code>
+       *
+       * <pre>
+       * One-of:
+       * </pre>
+       */
+      public boolean hasResolved() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Resolved resolved = 2;</code>
+       *
+       * <pre>
+       * One-of:
+       * </pre>
+       */
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved getResolved() {
+        return resolved_;
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Resolved resolved = 2;</code>
+       *
+       * <pre>
+       * One-of:
+       * </pre>
+       */
+      public Builder setResolved(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        resolved_ = value;
+
+        bitField0_ |= 0x00000002;
+        return this;
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Resolved resolved = 2;</code>
+       *
+       * <pre>
+       * One-of:
+       * </pre>
+       */
+      public Builder setResolved(
+          org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved.Builder builderForValue) {
+        resolved_ = builderForValue.build();
+
+        bitField0_ |= 0x00000002;
+        return this;
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Resolved resolved = 2;</code>
+       *
+       * <pre>
+       * One-of:
+       * </pre>
+       */
+      public Builder mergeResolved(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved value) {
+        if (((bitField0_ & 0x00000002) == 0x00000002) &&
+            resolved_ != org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved.getDefaultInstance()) {
+          resolved_ =
+            org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved.newBuilder(resolved_).mergeFrom(value).buildPartial();
+        } else {
+          resolved_ = value;
+        }
+
+        bitField0_ |= 0x00000002;
+        return this;
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Resolved resolved = 2;</code>
+       *
+       * <pre>
+       * One-of:
+       * </pre>
+       */
+      public Builder clearResolved() {
+        resolved_ = org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved.getDefaultInstance();
+
+        bitField0_ = (bitField0_ & ~0x00000002);
+        return this;
+      }
+
+      private org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error error_ = org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error.getDefaultInstance();
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Error error = 3;</code>
+       */
+      public boolean hasError() {
+        return ((bitField0_ & 0x00000004) == 0x00000004);
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Error error = 3;</code>
+       */
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error getError() {
+        return error_;
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Error error = 3;</code>
+       */
+      public Builder setError(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        error_ = value;
+
+        bitField0_ |= 0x00000004;
+        return this;
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Error error = 3;</code>
+       */
+      public Builder setError(
+          org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error.Builder builderForValue) {
+        error_ = builderForValue.build();
+
+        bitField0_ |= 0x00000004;
+        return this;
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Error error = 3;</code>
+       */
+      public Builder mergeError(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error value) {
+        if (((bitField0_ & 0x00000004) == 0x00000004) &&
+            error_ != org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error.getDefaultInstance()) {
+          error_ =
+            org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error.newBuilder(error_).mergeFrom(value).buildPartial();
+        } else {
+          error_ = value;
+        }
+
+        bitField0_ |= 0x00000004;
+        return this;
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Error error = 3;</code>
+       */
+      public Builder clearError() {
+        error_ = org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error.getDefaultInstance();
+
+        bitField0_ = (bitField0_ & ~0x00000004);
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Expression)
+    }
+
+    static {
+      defaultInstance = new Expression(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Expression)
+  }
+
+  public interface ResolvedOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Resolved)
+      org.jetbrains.kotlin.protobuf.MessageLiteOrBuilder {
+
+    /**
+     * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor candidate_descriptor = 1;</code>
+     */
+    boolean hasCandidateDescriptor();
+    /**
+     * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor candidate_descriptor = 1;</code>
+     */
+    org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor getCandidateDescriptor();
+
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type_argument = 2;</code>
+     */
+    java.util.List<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type> 
+        getTypeArgumentList();
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type_argument = 2;</code>
+     */
+    org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type getTypeArgument(int index);
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type_argument = 2;</code>
+     */
+    int getTypeArgumentCount();
+  }
+  /**
+   * Protobuf type {@code org.jetbrains.kotlin.cli.jvm.compiler.tmp.Resolved}
+   */
+  public static final class Resolved extends
+      org.jetbrains.kotlin.protobuf.GeneratedMessageLite implements
+      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Resolved)
+      ResolvedOrBuilder {
+    // Use Resolved.newBuilder() to construct.
+    private Resolved(org.jetbrains.kotlin.protobuf.GeneratedMessageLite.Builder builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private Resolved(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.ByteString.EMPTY;}
+
+    private static final Resolved defaultInstance;
+    public static Resolved getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public Resolved getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final org.jetbrains.kotlin.protobuf.ByteString unknownFields;
+    private Resolved(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      org.jetbrains.kotlin.protobuf.ByteString.Output unknownFieldsOutput =
+          org.jetbrains.kotlin.protobuf.ByteString.newOutput();
+      org.jetbrains.kotlin.protobuf.CodedOutputStream unknownFieldsCodedOutput =
+          org.jetbrains.kotlin.protobuf.CodedOutputStream.newInstance(
+              unknownFieldsOutput);
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFieldsCodedOutput,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+                subBuilder = candidateDescriptor_.toBuilder();
+              }
+              candidateDescriptor_ = input.readMessage(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(candidateDescriptor_);
+                candidateDescriptor_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000001;
+              break;
+            }
+            case 18: {
+              if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+                typeArgument_ = new java.util.ArrayList<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type>();
+                mutable_bitField0_ |= 0x00000002;
+              }
+              typeArgument_.add(input.readMessage(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type.PARSER, extensionRegistry));
+              break;
+            }
+          }
+        }
+      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+          typeArgument_ = java.util.Collections.unmodifiableList(typeArgument_);
+        }
+        try {
+          unknownFieldsCodedOutput.flush();
+        } catch (java.io.IOException e) {
+        // Should not happen
+        } finally {
+          unknownFields = unknownFieldsOutput.toByteString();
+        }
+        makeExtensionsImmutable();
+      }
+    }
+    public static org.jetbrains.kotlin.protobuf.Parser<Resolved> PARSER =
+        new org.jetbrains.kotlin.protobuf.AbstractParser<Resolved>() {
+      public Resolved parsePartialFrom(
+          org.jetbrains.kotlin.protobuf.CodedInputStream input,
+          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+        return new Resolved(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public org.jetbrains.kotlin.protobuf.Parser<Resolved> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    public static final int CANDIDATE_DESCRIPTOR_FIELD_NUMBER = 1;
+    private org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor candidateDescriptor_;
+    /**
+     * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor candidate_descriptor = 1;</code>
+     */
+    public boolean hasCandidateDescriptor() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor candidate_descriptor = 1;</code>
+     */
+    public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor getCandidateDescriptor() {
+      return candidateDescriptor_;
+    }
+
+    public static final int TYPE_ARGUMENT_FIELD_NUMBER = 2;
+    private java.util.List<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type> typeArgument_;
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type_argument = 2;</code>
+     */
+    public java.util.List<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type> getTypeArgumentList() {
+      return typeArgument_;
+    }
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type_argument = 2;</code>
+     */
+    public java.util.List<? extends org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.TypeOrBuilder> 
+        getTypeArgumentOrBuilderList() {
+      return typeArgument_;
+    }
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type_argument = 2;</code>
+     */
+    public int getTypeArgumentCount() {
+      return typeArgument_.size();
+    }
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type_argument = 2;</code>
+     */
+    public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type getTypeArgument(int index) {
+      return typeArgument_.get(index);
+    }
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type_argument = 2;</code>
+     */
+    public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.TypeOrBuilder getTypeArgumentOrBuilder(
+        int index) {
+      return typeArgument_.get(index);
+    }
+
+    private void initFields() {
+      candidateDescriptor_ = org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor.getDefaultInstance();
+      typeArgument_ = java.util.Collections.emptyList();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeMessage(1, candidateDescriptor_);
+      }
+      for (int i = 0; i < typeArgument_.size(); i++) {
+        output.writeMessage(2, typeArgument_.get(i));
+      }
+      output.writeRawBytes(unknownFields);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
+          .computeMessageSize(1, candidateDescriptor_);
+      }
+      for (int i = 0; i < typeArgument_.size(); i++) {
+        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
+          .computeMessageSize(2, typeArgument_.get(i));
+      }
+      size += unknownFields.size();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved parseFrom(
+        org.jetbrains.kotlin.protobuf.ByteString data)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved parseFrom(
+        org.jetbrains.kotlin.protobuf.ByteString data,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved parseFrom(byte[] data)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved parseFrom(
+        byte[] data,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved parseFrom(
+        java.io.InputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved parseDelimitedFrom(
+        java.io.InputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved parseFrom(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved parseFrom(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    /**
+     * Protobuf type {@code org.jetbrains.kotlin.cli.jvm.compiler.tmp.Resolved}
+     */
+    public static final class Builder extends
+        org.jetbrains.kotlin.protobuf.GeneratedMessageLite.Builder<
+          org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved, Builder>
+        implements
+        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Resolved)
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ResolvedOrBuilder {
+      // Construct using org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private void maybeForceBuilderInitialization() {
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        candidateDescriptor_ = org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor.getDefaultInstance();
+        bitField0_ = (bitField0_ & ~0x00000001);
+        typeArgument_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000002);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved getDefaultInstanceForType() {
+        return org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved.getDefaultInstance();
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved build() {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved buildPartial() {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved result = new org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.candidateDescriptor_ = candidateDescriptor_;
+        if (((bitField0_ & 0x00000002) == 0x00000002)) {
+          typeArgument_ = java.util.Collections.unmodifiableList(typeArgument_);
+          bitField0_ = (bitField0_ & ~0x00000002);
+        }
+        result.typeArgument_ = typeArgument_;
+        result.bitField0_ = to_bitField0_;
+        return result;
+      }
+
+      public Builder mergeFrom(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved other) {
+        if (other == org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved.getDefaultInstance()) return this;
+        if (other.hasCandidateDescriptor()) {
+          mergeCandidateDescriptor(other.getCandidateDescriptor());
+        }
+        if (!other.typeArgument_.isEmpty()) {
+          if (typeArgument_.isEmpty()) {
+            typeArgument_ = other.typeArgument_;
+            bitField0_ = (bitField0_ & ~0x00000002);
+          } else {
+            ensureTypeArgumentIsMutable();
+            typeArgument_.addAll(other.typeArgument_);
+          }
+          
+        }
+        setUnknownFields(
+            getUnknownFields().concat(other.unknownFields));
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          org.jetbrains.kotlin.protobuf.CodedInputStream input,
+          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Resolved) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      private org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor candidateDescriptor_ = org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor.getDefaultInstance();
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor candidate_descriptor = 1;</code>
+       */
+      public boolean hasCandidateDescriptor() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor candidate_descriptor = 1;</code>
+       */
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor getCandidateDescriptor() {
+        return candidateDescriptor_;
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor candidate_descriptor = 1;</code>
+       */
+      public Builder setCandidateDescriptor(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        candidateDescriptor_ = value;
+
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor candidate_descriptor = 1;</code>
+       */
+      public Builder setCandidateDescriptor(
+          org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor.Builder builderForValue) {
+        candidateDescriptor_ = builderForValue.build();
+
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor candidate_descriptor = 1;</code>
+       */
+      public Builder mergeCandidateDescriptor(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor value) {
+        if (((bitField0_ & 0x00000001) == 0x00000001) &&
+            candidateDescriptor_ != org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor.getDefaultInstance()) {
+          candidateDescriptor_ =
+            org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor.newBuilder(candidateDescriptor_).mergeFrom(value).buildPartial();
+        } else {
+          candidateDescriptor_ = value;
+        }
+
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>optional .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor candidate_descriptor = 1;</code>
+       */
+      public Builder clearCandidateDescriptor() {
+        candidateDescriptor_ = org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor.getDefaultInstance();
+
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+
+      private java.util.List<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type> typeArgument_ =
+        java.util.Collections.emptyList();
+      private void ensureTypeArgumentIsMutable() {
+        if (!((bitField0_ & 0x00000002) == 0x00000002)) {
+          typeArgument_ = new java.util.ArrayList<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type>(typeArgument_);
+          bitField0_ |= 0x00000002;
+         }
+      }
+
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type_argument = 2;</code>
+       */
+      public java.util.List<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type> getTypeArgumentList() {
+        return java.util.Collections.unmodifiableList(typeArgument_);
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type_argument = 2;</code>
+       */
+      public int getTypeArgumentCount() {
+        return typeArgument_.size();
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type_argument = 2;</code>
+       */
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type getTypeArgument(int index) {
+        return typeArgument_.get(index);
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type_argument = 2;</code>
+       */
+      public Builder setTypeArgument(
+          int index, org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureTypeArgumentIsMutable();
+        typeArgument_.set(index, value);
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type_argument = 2;</code>
+       */
+      public Builder setTypeArgument(
+          int index, org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type.Builder builderForValue) {
+        ensureTypeArgumentIsMutable();
+        typeArgument_.set(index, builderForValue.build());
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type_argument = 2;</code>
+       */
+      public Builder addTypeArgument(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureTypeArgumentIsMutable();
+        typeArgument_.add(value);
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type_argument = 2;</code>
+       */
+      public Builder addTypeArgument(
+          int index, org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureTypeArgumentIsMutable();
+        typeArgument_.add(index, value);
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type_argument = 2;</code>
+       */
+      public Builder addTypeArgument(
+          org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type.Builder builderForValue) {
+        ensureTypeArgumentIsMutable();
+        typeArgument_.add(builderForValue.build());
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type_argument = 2;</code>
+       */
+      public Builder addTypeArgument(
+          int index, org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type.Builder builderForValue) {
+        ensureTypeArgumentIsMutable();
+        typeArgument_.add(index, builderForValue.build());
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type_argument = 2;</code>
+       */
+      public Builder addAllTypeArgument(
+          java.lang.Iterable<? extends org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type> values) {
+        ensureTypeArgumentIsMutable();
+        org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll(
+            values, typeArgument_);
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type_argument = 2;</code>
+       */
+      public Builder clearTypeArgument() {
+        typeArgument_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000002);
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type type_argument = 2;</code>
+       */
+      public Builder removeTypeArgument(int index) {
+        ensureTypeArgumentIsMutable();
+        typeArgument_.remove(index);
+
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Resolved)
+    }
+
+    static {
+      defaultInstance = new Resolved(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Resolved)
+  }
+
+  public interface ErrorOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Error)
+      org.jetbrains.kotlin.protobuf.MessageLiteOrBuilder {
+
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic diagnostic = 1;</code>
+     */
+    java.util.List<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic> 
+        getDiagnosticList();
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic diagnostic = 1;</code>
+     */
+    org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic getDiagnostic(int index);
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic diagnostic = 1;</code>
+     */
+    int getDiagnosticCount();
+  }
+  /**
+   * Protobuf type {@code org.jetbrains.kotlin.cli.jvm.compiler.tmp.Error}
+   */
+  public static final class Error extends
+      org.jetbrains.kotlin.protobuf.GeneratedMessageLite implements
+      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Error)
+      ErrorOrBuilder {
+    // Use Error.newBuilder() to construct.
+    private Error(org.jetbrains.kotlin.protobuf.GeneratedMessageLite.Builder builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private Error(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.ByteString.EMPTY;}
+
+    private static final Error defaultInstance;
+    public static Error getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public Error getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final org.jetbrains.kotlin.protobuf.ByteString unknownFields;
+    private Error(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      org.jetbrains.kotlin.protobuf.ByteString.Output unknownFieldsOutput =
+          org.jetbrains.kotlin.protobuf.ByteString.newOutput();
+      org.jetbrains.kotlin.protobuf.CodedOutputStream unknownFieldsCodedOutput =
+          org.jetbrains.kotlin.protobuf.CodedOutputStream.newInstance(
+              unknownFieldsOutput);
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFieldsCodedOutput,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+                diagnostic_ = new java.util.ArrayList<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              diagnostic_.add(input.readMessage(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic.PARSER, extensionRegistry));
+              break;
+            }
+          }
+        }
+      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+          diagnostic_ = java.util.Collections.unmodifiableList(diagnostic_);
+        }
+        try {
+          unknownFieldsCodedOutput.flush();
+        } catch (java.io.IOException e) {
+        // Should not happen
+        } finally {
+          unknownFields = unknownFieldsOutput.toByteString();
+        }
+        makeExtensionsImmutable();
+      }
+    }
+    public static org.jetbrains.kotlin.protobuf.Parser<Error> PARSER =
+        new org.jetbrains.kotlin.protobuf.AbstractParser<Error>() {
+      public Error parsePartialFrom(
+          org.jetbrains.kotlin.protobuf.CodedInputStream input,
+          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+        return new Error(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public org.jetbrains.kotlin.protobuf.Parser<Error> getParserForType() {
+      return PARSER;
+    }
+
+    public static final int DIAGNOSTIC_FIELD_NUMBER = 1;
+    private java.util.List<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic> diagnostic_;
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic diagnostic = 1;</code>
+     */
+    public java.util.List<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic> getDiagnosticList() {
+      return diagnostic_;
+    }
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic diagnostic = 1;</code>
+     */
+    public java.util.List<? extends org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.DiagnosticOrBuilder> 
+        getDiagnosticOrBuilderList() {
+      return diagnostic_;
+    }
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic diagnostic = 1;</code>
+     */
+    public int getDiagnosticCount() {
+      return diagnostic_.size();
+    }
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic diagnostic = 1;</code>
+     */
+    public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic getDiagnostic(int index) {
+      return diagnostic_.get(index);
+    }
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic diagnostic = 1;</code>
+     */
+    public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.DiagnosticOrBuilder getDiagnosticOrBuilder(
+        int index) {
+      return diagnostic_.get(index);
+    }
+
+    private void initFields() {
+      diagnostic_ = java.util.Collections.emptyList();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      for (int i = 0; i < diagnostic_.size(); i++) {
+        output.writeMessage(1, diagnostic_.get(i));
+      }
+      output.writeRawBytes(unknownFields);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      for (int i = 0; i < diagnostic_.size(); i++) {
+        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
+          .computeMessageSize(1, diagnostic_.get(i));
+      }
+      size += unknownFields.size();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error parseFrom(
+        org.jetbrains.kotlin.protobuf.ByteString data)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error parseFrom(
+        org.jetbrains.kotlin.protobuf.ByteString data,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error parseFrom(byte[] data)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error parseFrom(
+        byte[] data,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error parseFrom(
+        java.io.InputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error parseDelimitedFrom(
+        java.io.InputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error parseFrom(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error parseFrom(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    /**
+     * Protobuf type {@code org.jetbrains.kotlin.cli.jvm.compiler.tmp.Error}
+     */
+    public static final class Builder extends
+        org.jetbrains.kotlin.protobuf.GeneratedMessageLite.Builder<
+          org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error, Builder>
+        implements
+        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Error)
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.ErrorOrBuilder {
+      // Construct using org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private void maybeForceBuilderInitialization() {
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        diagnostic_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error getDefaultInstanceForType() {
+        return org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error.getDefaultInstance();
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error build() {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error buildPartial() {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error result = new org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error(this);
+        int from_bitField0_ = bitField0_;
+        if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          diagnostic_ = java.util.Collections.unmodifiableList(diagnostic_);
+          bitField0_ = (bitField0_ & ~0x00000001);
+        }
+        result.diagnostic_ = diagnostic_;
+        return result;
+      }
+
+      public Builder mergeFrom(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error other) {
+        if (other == org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error.getDefaultInstance()) return this;
+        if (!other.diagnostic_.isEmpty()) {
+          if (diagnostic_.isEmpty()) {
+            diagnostic_ = other.diagnostic_;
+            bitField0_ = (bitField0_ & ~0x00000001);
+          } else {
+            ensureDiagnosticIsMutable();
+            diagnostic_.addAll(other.diagnostic_);
+          }
+          
+        }
+        setUnknownFields(
+            getUnknownFields().concat(other.unknownFields));
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          org.jetbrains.kotlin.protobuf.CodedInputStream input,
+          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Error) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      private java.util.List<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic> diagnostic_ =
+        java.util.Collections.emptyList();
+      private void ensureDiagnosticIsMutable() {
+        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+          diagnostic_ = new java.util.ArrayList<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic>(diagnostic_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic diagnostic = 1;</code>
+       */
+      public java.util.List<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic> getDiagnosticList() {
+        return java.util.Collections.unmodifiableList(diagnostic_);
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic diagnostic = 1;</code>
+       */
+      public int getDiagnosticCount() {
+        return diagnostic_.size();
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic diagnostic = 1;</code>
+       */
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic getDiagnostic(int index) {
+        return diagnostic_.get(index);
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic diagnostic = 1;</code>
+       */
+      public Builder setDiagnostic(
+          int index, org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureDiagnosticIsMutable();
+        diagnostic_.set(index, value);
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic diagnostic = 1;</code>
+       */
+      public Builder setDiagnostic(
+          int index, org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic.Builder builderForValue) {
+        ensureDiagnosticIsMutable();
+        diagnostic_.set(index, builderForValue.build());
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic diagnostic = 1;</code>
+       */
+      public Builder addDiagnostic(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureDiagnosticIsMutable();
+        diagnostic_.add(value);
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic diagnostic = 1;</code>
+       */
+      public Builder addDiagnostic(
+          int index, org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureDiagnosticIsMutable();
+        diagnostic_.add(index, value);
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic diagnostic = 1;</code>
+       */
+      public Builder addDiagnostic(
+          org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic.Builder builderForValue) {
+        ensureDiagnosticIsMutable();
+        diagnostic_.add(builderForValue.build());
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic diagnostic = 1;</code>
+       */
+      public Builder addDiagnostic(
+          int index, org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic.Builder builderForValue) {
+        ensureDiagnosticIsMutable();
+        diagnostic_.add(index, builderForValue.build());
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic diagnostic = 1;</code>
+       */
+      public Builder addAllDiagnostic(
+          java.lang.Iterable<? extends org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic> values) {
+        ensureDiagnosticIsMutable();
+        org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll(
+            values, diagnostic_);
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic diagnostic = 1;</code>
+       */
+      public Builder clearDiagnostic() {
+        diagnostic_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic diagnostic = 1;</code>
+       */
+      public Builder removeDiagnostic(int index) {
+        ensureDiagnosticIsMutable();
+        diagnostic_.remove(index);
+
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Error)
+    }
+
+    static {
+      defaultInstance = new Error(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Error)
+  }
+
+  public interface DiagnosticOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic)
+      org.jetbrains.kotlin.protobuf.MessageLiteOrBuilder {
+
+    /**
+     * <code>optional string diagnostic_family = 1;</code>
+     *
+     * <pre>
+     * TODO: stub
+     * </pre>
+     */
+    boolean hasDiagnosticFamily();
+    /**
+     * <code>optional string diagnostic_family = 1;</code>
+     *
+     * <pre>
+     * TODO: stub
+     * </pre>
+     */
+    java.lang.String getDiagnosticFamily();
+    /**
+     * <code>optional string diagnostic_family = 1;</code>
+     *
+     * <pre>
+     * TODO: stub
+     * </pre>
+     */
+    org.jetbrains.kotlin.protobuf.ByteString
+        getDiagnosticFamilyBytes();
+
+    /**
+     * <code>optional string rendered_text = 2;</code>
+     */
+    boolean hasRenderedText();
+    /**
+     * <code>optional string rendered_text = 2;</code>
+     */
+    java.lang.String getRenderedText();
+    /**
+     * <code>optional string rendered_text = 2;</code>
+     */
+    org.jetbrains.kotlin.protobuf.ByteString
+        getRenderedTextBytes();
+  }
+  /**
+   * Protobuf type {@code org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic}
+   */
+  public static final class Diagnostic extends
+      org.jetbrains.kotlin.protobuf.GeneratedMessageLite implements
+      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic)
+      DiagnosticOrBuilder {
+    // Use Diagnostic.newBuilder() to construct.
+    private Diagnostic(org.jetbrains.kotlin.protobuf.GeneratedMessageLite.Builder builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private Diagnostic(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.ByteString.EMPTY;}
+
+    private static final Diagnostic defaultInstance;
+    public static Diagnostic getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public Diagnostic getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final org.jetbrains.kotlin.protobuf.ByteString unknownFields;
+    private Diagnostic(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      org.jetbrains.kotlin.protobuf.ByteString.Output unknownFieldsOutput =
+          org.jetbrains.kotlin.protobuf.ByteString.newOutput();
+      org.jetbrains.kotlin.protobuf.CodedOutputStream unknownFieldsCodedOutput =
+          org.jetbrains.kotlin.protobuf.CodedOutputStream.newInstance(
+              unknownFieldsOutput);
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFieldsCodedOutput,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              org.jetbrains.kotlin.protobuf.ByteString bs = input.readBytes();
+              bitField0_ |= 0x00000001;
+              diagnosticFamily_ = bs;
+              break;
+            }
+            case 18: {
+              org.jetbrains.kotlin.protobuf.ByteString bs = input.readBytes();
+              bitField0_ |= 0x00000002;
+              renderedText_ = bs;
+              break;
+            }
+          }
+        }
+      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        try {
+          unknownFieldsCodedOutput.flush();
+        } catch (java.io.IOException e) {
+        // Should not happen
+        } finally {
+          unknownFields = unknownFieldsOutput.toByteString();
+        }
+        makeExtensionsImmutable();
+      }
+    }
+    public static org.jetbrains.kotlin.protobuf.Parser<Diagnostic> PARSER =
+        new org.jetbrains.kotlin.protobuf.AbstractParser<Diagnostic>() {
+      public Diagnostic parsePartialFrom(
+          org.jetbrains.kotlin.protobuf.CodedInputStream input,
+          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+        return new Diagnostic(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public org.jetbrains.kotlin.protobuf.Parser<Diagnostic> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    public static final int DIAGNOSTIC_FAMILY_FIELD_NUMBER = 1;
+    private java.lang.Object diagnosticFamily_;
+    /**
+     * <code>optional string diagnostic_family = 1;</code>
+     *
+     * <pre>
+     * TODO: stub
+     * </pre>
+     */
+    public boolean hasDiagnosticFamily() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>optional string diagnostic_family = 1;</code>
+     *
+     * <pre>
+     * TODO: stub
+     * </pre>
+     */
+    public java.lang.String getDiagnosticFamily() {
+      java.lang.Object ref = diagnosticFamily_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        org.jetbrains.kotlin.protobuf.ByteString bs = 
+            (org.jetbrains.kotlin.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          diagnosticFamily_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>optional string diagnostic_family = 1;</code>
+     *
+     * <pre>
+     * TODO: stub
+     * </pre>
+     */
+    public org.jetbrains.kotlin.protobuf.ByteString
+        getDiagnosticFamilyBytes() {
+      java.lang.Object ref = diagnosticFamily_;
+      if (ref instanceof java.lang.String) {
+        org.jetbrains.kotlin.protobuf.ByteString b = 
+            org.jetbrains.kotlin.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        diagnosticFamily_ = b;
+        return b;
+      } else {
+        return (org.jetbrains.kotlin.protobuf.ByteString) ref;
+      }
+    }
+
+    public static final int RENDERED_TEXT_FIELD_NUMBER = 2;
+    private java.lang.Object renderedText_;
+    /**
+     * <code>optional string rendered_text = 2;</code>
+     */
+    public boolean hasRenderedText() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>optional string rendered_text = 2;</code>
+     */
+    public java.lang.String getRenderedText() {
+      java.lang.Object ref = renderedText_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        org.jetbrains.kotlin.protobuf.ByteString bs = 
+            (org.jetbrains.kotlin.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          renderedText_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>optional string rendered_text = 2;</code>
+     */
+    public org.jetbrains.kotlin.protobuf.ByteString
+        getRenderedTextBytes() {
+      java.lang.Object ref = renderedText_;
+      if (ref instanceof java.lang.String) {
+        org.jetbrains.kotlin.protobuf.ByteString b = 
+            org.jetbrains.kotlin.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        renderedText_ = b;
+        return b;
+      } else {
+        return (org.jetbrains.kotlin.protobuf.ByteString) ref;
+      }
+    }
+
+    private void initFields() {
+      diagnosticFamily_ = "";
+      renderedText_ = "";
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBytes(1, getDiagnosticFamilyBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeBytes(2, getRenderedTextBytes());
+      }
+      output.writeRawBytes(unknownFields);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
+          .computeBytesSize(1, getDiagnosticFamilyBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
+          .computeBytesSize(2, getRenderedTextBytes());
+      }
+      size += unknownFields.size();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic parseFrom(
+        org.jetbrains.kotlin.protobuf.ByteString data)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic parseFrom(
+        org.jetbrains.kotlin.protobuf.ByteString data,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic parseFrom(byte[] data)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic parseFrom(
+        byte[] data,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic parseFrom(
+        java.io.InputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic parseDelimitedFrom(
+        java.io.InputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic parseFrom(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic parseFrom(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    /**
+     * Protobuf type {@code org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic}
+     */
+    public static final class Builder extends
+        org.jetbrains.kotlin.protobuf.GeneratedMessageLite.Builder<
+          org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic, Builder>
+        implements
+        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic)
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.DiagnosticOrBuilder {
+      // Construct using org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private void maybeForceBuilderInitialization() {
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        diagnosticFamily_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
+        renderedText_ = "";
+        bitField0_ = (bitField0_ & ~0x00000002);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic getDefaultInstanceForType() {
+        return org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic.getDefaultInstance();
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic build() {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic buildPartial() {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic result = new org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.diagnosticFamily_ = diagnosticFamily_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.renderedText_ = renderedText_;
+        result.bitField0_ = to_bitField0_;
+        return result;
+      }
+
+      public Builder mergeFrom(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic other) {
+        if (other == org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic.getDefaultInstance()) return this;
+        if (other.hasDiagnosticFamily()) {
+          bitField0_ |= 0x00000001;
+          diagnosticFamily_ = other.diagnosticFamily_;
+          
+        }
+        if (other.hasRenderedText()) {
+          bitField0_ |= 0x00000002;
+          renderedText_ = other.renderedText_;
+          
+        }
+        setUnknownFields(
+            getUnknownFields().concat(other.unknownFields));
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          org.jetbrains.kotlin.protobuf.CodedInputStream input,
+          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Diagnostic) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      private java.lang.Object diagnosticFamily_ = "";
+      /**
+       * <code>optional string diagnostic_family = 1;</code>
+       *
+       * <pre>
+       * TODO: stub
+       * </pre>
+       */
+      public boolean hasDiagnosticFamily() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>optional string diagnostic_family = 1;</code>
+       *
+       * <pre>
+       * TODO: stub
+       * </pre>
+       */
+      public java.lang.String getDiagnosticFamily() {
+        java.lang.Object ref = diagnosticFamily_;
+        if (!(ref instanceof java.lang.String)) {
+          org.jetbrains.kotlin.protobuf.ByteString bs =
+              (org.jetbrains.kotlin.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          if (bs.isValidUtf8()) {
+            diagnosticFamily_ = s;
+          }
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string diagnostic_family = 1;</code>
+       *
+       * <pre>
+       * TODO: stub
+       * </pre>
+       */
+      public org.jetbrains.kotlin.protobuf.ByteString
+          getDiagnosticFamilyBytes() {
+        java.lang.Object ref = diagnosticFamily_;
+        if (ref instanceof String) {
+          org.jetbrains.kotlin.protobuf.ByteString b = 
+              org.jetbrains.kotlin.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          diagnosticFamily_ = b;
+          return b;
+        } else {
+          return (org.jetbrains.kotlin.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string diagnostic_family = 1;</code>
+       *
+       * <pre>
+       * TODO: stub
+       * </pre>
+       */
+      public Builder setDiagnosticFamily(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        diagnosticFamily_ = value;
+        
+        return this;
+      }
+      /**
+       * <code>optional string diagnostic_family = 1;</code>
+       *
+       * <pre>
+       * TODO: stub
+       * </pre>
+       */
+      public Builder clearDiagnosticFamily() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        diagnosticFamily_ = getDefaultInstance().getDiagnosticFamily();
+        
+        return this;
+      }
+      /**
+       * <code>optional string diagnostic_family = 1;</code>
+       *
+       * <pre>
+       * TODO: stub
+       * </pre>
+       */
+      public Builder setDiagnosticFamilyBytes(
+          org.jetbrains.kotlin.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        diagnosticFamily_ = value;
+        
+        return this;
+      }
+
+      private java.lang.Object renderedText_ = "";
+      /**
+       * <code>optional string rendered_text = 2;</code>
+       */
+      public boolean hasRenderedText() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>optional string rendered_text = 2;</code>
+       */
+      public java.lang.String getRenderedText() {
+        java.lang.Object ref = renderedText_;
+        if (!(ref instanceof java.lang.String)) {
+          org.jetbrains.kotlin.protobuf.ByteString bs =
+              (org.jetbrains.kotlin.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          if (bs.isValidUtf8()) {
+            renderedText_ = s;
+          }
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string rendered_text = 2;</code>
+       */
+      public org.jetbrains.kotlin.protobuf.ByteString
+          getRenderedTextBytes() {
+        java.lang.Object ref = renderedText_;
+        if (ref instanceof String) {
+          org.jetbrains.kotlin.protobuf.ByteString b = 
+              org.jetbrains.kotlin.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          renderedText_ = b;
+          return b;
+        } else {
+          return (org.jetbrains.kotlin.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string rendered_text = 2;</code>
+       */
+      public Builder setRenderedText(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        renderedText_ = value;
+        
+        return this;
+      }
+      /**
+       * <code>optional string rendered_text = 2;</code>
+       */
+      public Builder clearRenderedText() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        renderedText_ = getDefaultInstance().getRenderedText();
+        
+        return this;
+      }
+      /**
+       * <code>optional string rendered_text = 2;</code>
+       */
+      public Builder setRenderedTextBytes(
+          org.jetbrains.kotlin.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        renderedText_ = value;
+        
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic)
+    }
+
+    static {
+      defaultInstance = new Diagnostic(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Diagnostic)
+  }
+
+  public interface DescriptorOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor)
+      org.jetbrains.kotlin.protobuf.MessageLiteOrBuilder {
+
+    /**
+     * <code>optional string fqn = 1;</code>
+     *
+     * <pre>
+     * TODO: stub
+     * </pre>
+     */
+    boolean hasFqn();
+    /**
+     * <code>optional string fqn = 1;</code>
+     *
+     * <pre>
+     * TODO: stub
+     * </pre>
+     */
+    java.lang.String getFqn();
+    /**
+     * <code>optional string fqn = 1;</code>
+     *
+     * <pre>
+     * TODO: stub
+     * </pre>
+     */
+    org.jetbrains.kotlin.protobuf.ByteString
+        getFqnBytes();
+
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor type_parameter = 2;</code>
+     */
+    java.util.List<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor> 
+        getTypeParameterList();
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor type_parameter = 2;</code>
+     */
+    org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor getTypeParameter(int index);
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor type_parameter = 2;</code>
+     */
+    int getTypeParameterCount();
+  }
+  /**
+   * Protobuf type {@code org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor}
+   */
+  public static final class Descriptor extends
+      org.jetbrains.kotlin.protobuf.GeneratedMessageLite implements
+      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor)
+      DescriptorOrBuilder {
+    // Use Descriptor.newBuilder() to construct.
+    private Descriptor(org.jetbrains.kotlin.protobuf.GeneratedMessageLite.Builder builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private Descriptor(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.ByteString.EMPTY;}
+
+    private static final Descriptor defaultInstance;
+    public static Descriptor getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public Descriptor getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final org.jetbrains.kotlin.protobuf.ByteString unknownFields;
+    private Descriptor(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      org.jetbrains.kotlin.protobuf.ByteString.Output unknownFieldsOutput =
+          org.jetbrains.kotlin.protobuf.ByteString.newOutput();
+      org.jetbrains.kotlin.protobuf.CodedOutputStream unknownFieldsCodedOutput =
+          org.jetbrains.kotlin.protobuf.CodedOutputStream.newInstance(
+              unknownFieldsOutput);
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFieldsCodedOutput,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              org.jetbrains.kotlin.protobuf.ByteString bs = input.readBytes();
+              bitField0_ |= 0x00000001;
+              fqn_ = bs;
+              break;
+            }
+            case 18: {
+              if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+                typeParameter_ = new java.util.ArrayList<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor>();
+                mutable_bitField0_ |= 0x00000002;
+              }
+              typeParameter_.add(input.readMessage(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor.PARSER, extensionRegistry));
+              break;
+            }
+          }
+        }
+      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+          typeParameter_ = java.util.Collections.unmodifiableList(typeParameter_);
+        }
+        try {
+          unknownFieldsCodedOutput.flush();
+        } catch (java.io.IOException e) {
+        // Should not happen
+        } finally {
+          unknownFields = unknownFieldsOutput.toByteString();
+        }
+        makeExtensionsImmutable();
+      }
+    }
+    public static org.jetbrains.kotlin.protobuf.Parser<Descriptor> PARSER =
+        new org.jetbrains.kotlin.protobuf.AbstractParser<Descriptor>() {
+      public Descriptor parsePartialFrom(
+          org.jetbrains.kotlin.protobuf.CodedInputStream input,
+          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+        return new Descriptor(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public org.jetbrains.kotlin.protobuf.Parser<Descriptor> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    public static final int FQN_FIELD_NUMBER = 1;
+    private java.lang.Object fqn_;
+    /**
+     * <code>optional string fqn = 1;</code>
+     *
+     * <pre>
+     * TODO: stub
+     * </pre>
+     */
+    public boolean hasFqn() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>optional string fqn = 1;</code>
+     *
+     * <pre>
+     * TODO: stub
+     * </pre>
+     */
+    public java.lang.String getFqn() {
+      java.lang.Object ref = fqn_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        org.jetbrains.kotlin.protobuf.ByteString bs = 
+            (org.jetbrains.kotlin.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          fqn_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>optional string fqn = 1;</code>
+     *
+     * <pre>
+     * TODO: stub
+     * </pre>
+     */
+    public org.jetbrains.kotlin.protobuf.ByteString
+        getFqnBytes() {
+      java.lang.Object ref = fqn_;
+      if (ref instanceof java.lang.String) {
+        org.jetbrains.kotlin.protobuf.ByteString b = 
+            org.jetbrains.kotlin.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        fqn_ = b;
+        return b;
+      } else {
+        return (org.jetbrains.kotlin.protobuf.ByteString) ref;
+      }
+    }
+
+    public static final int TYPE_PARAMETER_FIELD_NUMBER = 2;
+    private java.util.List<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor> typeParameter_;
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor type_parameter = 2;</code>
+     */
+    public java.util.List<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor> getTypeParameterList() {
+      return typeParameter_;
+    }
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor type_parameter = 2;</code>
+     */
+    public java.util.List<? extends org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.DescriptorOrBuilder> 
+        getTypeParameterOrBuilderList() {
+      return typeParameter_;
+    }
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor type_parameter = 2;</code>
+     */
+    public int getTypeParameterCount() {
+      return typeParameter_.size();
+    }
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor type_parameter = 2;</code>
+     */
+    public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor getTypeParameter(int index) {
+      return typeParameter_.get(index);
+    }
+    /**
+     * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor type_parameter = 2;</code>
+     */
+    public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.DescriptorOrBuilder getTypeParameterOrBuilder(
+        int index) {
+      return typeParameter_.get(index);
+    }
+
+    private void initFields() {
+      fqn_ = "";
+      typeParameter_ = java.util.Collections.emptyList();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBytes(1, getFqnBytes());
+      }
+      for (int i = 0; i < typeParameter_.size(); i++) {
+        output.writeMessage(2, typeParameter_.get(i));
+      }
+      output.writeRawBytes(unknownFields);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
+          .computeBytesSize(1, getFqnBytes());
+      }
+      for (int i = 0; i < typeParameter_.size(); i++) {
+        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
+          .computeMessageSize(2, typeParameter_.get(i));
+      }
+      size += unknownFields.size();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor parseFrom(
+        org.jetbrains.kotlin.protobuf.ByteString data)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor parseFrom(
+        org.jetbrains.kotlin.protobuf.ByteString data,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor parseFrom(byte[] data)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor parseFrom(
+        byte[] data,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor parseFrom(
+        java.io.InputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor parseDelimitedFrom(
+        java.io.InputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor parseFrom(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor parseFrom(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    /**
+     * Protobuf type {@code org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor}
+     */
+    public static final class Builder extends
+        org.jetbrains.kotlin.protobuf.GeneratedMessageLite.Builder<
+          org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor, Builder>
+        implements
+        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor)
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.DescriptorOrBuilder {
+      // Construct using org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private void maybeForceBuilderInitialization() {
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        fqn_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
+        typeParameter_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000002);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor getDefaultInstanceForType() {
+        return org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor.getDefaultInstance();
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor build() {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor buildPartial() {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor result = new org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.fqn_ = fqn_;
+        if (((bitField0_ & 0x00000002) == 0x00000002)) {
+          typeParameter_ = java.util.Collections.unmodifiableList(typeParameter_);
+          bitField0_ = (bitField0_ & ~0x00000002);
+        }
+        result.typeParameter_ = typeParameter_;
+        result.bitField0_ = to_bitField0_;
+        return result;
+      }
+
+      public Builder mergeFrom(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor other) {
+        if (other == org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor.getDefaultInstance()) return this;
+        if (other.hasFqn()) {
+          bitField0_ |= 0x00000001;
+          fqn_ = other.fqn_;
+          
+        }
+        if (!other.typeParameter_.isEmpty()) {
+          if (typeParameter_.isEmpty()) {
+            typeParameter_ = other.typeParameter_;
+            bitField0_ = (bitField0_ & ~0x00000002);
+          } else {
+            ensureTypeParameterIsMutable();
+            typeParameter_.addAll(other.typeParameter_);
+          }
+          
+        }
+        setUnknownFields(
+            getUnknownFields().concat(other.unknownFields));
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          org.jetbrains.kotlin.protobuf.CodedInputStream input,
+          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      private java.lang.Object fqn_ = "";
+      /**
+       * <code>optional string fqn = 1;</code>
+       *
+       * <pre>
+       * TODO: stub
+       * </pre>
+       */
+      public boolean hasFqn() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>optional string fqn = 1;</code>
+       *
+       * <pre>
+       * TODO: stub
+       * </pre>
+       */
+      public java.lang.String getFqn() {
+        java.lang.Object ref = fqn_;
+        if (!(ref instanceof java.lang.String)) {
+          org.jetbrains.kotlin.protobuf.ByteString bs =
+              (org.jetbrains.kotlin.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          if (bs.isValidUtf8()) {
+            fqn_ = s;
+          }
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string fqn = 1;</code>
+       *
+       * <pre>
+       * TODO: stub
+       * </pre>
+       */
+      public org.jetbrains.kotlin.protobuf.ByteString
+          getFqnBytes() {
+        java.lang.Object ref = fqn_;
+        if (ref instanceof String) {
+          org.jetbrains.kotlin.protobuf.ByteString b = 
+              org.jetbrains.kotlin.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          fqn_ = b;
+          return b;
+        } else {
+          return (org.jetbrains.kotlin.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string fqn = 1;</code>
+       *
+       * <pre>
+       * TODO: stub
+       * </pre>
+       */
+      public Builder setFqn(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        fqn_ = value;
+        
+        return this;
+      }
+      /**
+       * <code>optional string fqn = 1;</code>
+       *
+       * <pre>
+       * TODO: stub
+       * </pre>
+       */
+      public Builder clearFqn() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        fqn_ = getDefaultInstance().getFqn();
+        
+        return this;
+      }
+      /**
+       * <code>optional string fqn = 1;</code>
+       *
+       * <pre>
+       * TODO: stub
+       * </pre>
+       */
+      public Builder setFqnBytes(
+          org.jetbrains.kotlin.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        fqn_ = value;
+        
+        return this;
+      }
+
+      private java.util.List<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor> typeParameter_ =
+        java.util.Collections.emptyList();
+      private void ensureTypeParameterIsMutable() {
+        if (!((bitField0_ & 0x00000002) == 0x00000002)) {
+          typeParameter_ = new java.util.ArrayList<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor>(typeParameter_);
+          bitField0_ |= 0x00000002;
+         }
+      }
+
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor type_parameter = 2;</code>
+       */
+      public java.util.List<org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor> getTypeParameterList() {
+        return java.util.Collections.unmodifiableList(typeParameter_);
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor type_parameter = 2;</code>
+       */
+      public int getTypeParameterCount() {
+        return typeParameter_.size();
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor type_parameter = 2;</code>
+       */
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor getTypeParameter(int index) {
+        return typeParameter_.get(index);
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor type_parameter = 2;</code>
+       */
+      public Builder setTypeParameter(
+          int index, org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureTypeParameterIsMutable();
+        typeParameter_.set(index, value);
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor type_parameter = 2;</code>
+       */
+      public Builder setTypeParameter(
+          int index, org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor.Builder builderForValue) {
+        ensureTypeParameterIsMutable();
+        typeParameter_.set(index, builderForValue.build());
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor type_parameter = 2;</code>
+       */
+      public Builder addTypeParameter(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureTypeParameterIsMutable();
+        typeParameter_.add(value);
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor type_parameter = 2;</code>
+       */
+      public Builder addTypeParameter(
+          int index, org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureTypeParameterIsMutable();
+        typeParameter_.add(index, value);
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor type_parameter = 2;</code>
+       */
+      public Builder addTypeParameter(
+          org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor.Builder builderForValue) {
+        ensureTypeParameterIsMutable();
+        typeParameter_.add(builderForValue.build());
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor type_parameter = 2;</code>
+       */
+      public Builder addTypeParameter(
+          int index, org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor.Builder builderForValue) {
+        ensureTypeParameterIsMutable();
+        typeParameter_.add(index, builderForValue.build());
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor type_parameter = 2;</code>
+       */
+      public Builder addAllTypeParameter(
+          java.lang.Iterable<? extends org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Descriptor> values) {
+        ensureTypeParameterIsMutable();
+        org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll(
+            values, typeParameter_);
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor type_parameter = 2;</code>
+       */
+      public Builder clearTypeParameter() {
+        typeParameter_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000002);
+
+        return this;
+      }
+      /**
+       * <code>repeated .org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor type_parameter = 2;</code>
+       */
+      public Builder removeTypeParameter(int index) {
+        ensureTypeParameterIsMutable();
+        typeParameter_.remove(index);
+
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor)
+    }
+
+    static {
+      defaultInstance = new Descriptor(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Descriptor)
+  }
+
+  public interface TypeOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type)
+      org.jetbrains.kotlin.protobuf.MessageLiteOrBuilder {
+
+    /**
+     * <code>optional string rendered_type = 1;</code>
+     *
+     * <pre>
+     * TODO: stub
+     * </pre>
+     */
+    boolean hasRenderedType();
+    /**
+     * <code>optional string rendered_type = 1;</code>
+     *
+     * <pre>
+     * TODO: stub
+     * </pre>
+     */
+    java.lang.String getRenderedType();
+    /**
+     * <code>optional string rendered_type = 1;</code>
+     *
+     * <pre>
+     * TODO: stub
+     * </pre>
+     */
+    org.jetbrains.kotlin.protobuf.ByteString
+        getRenderedTypeBytes();
+  }
+  /**
+   * Protobuf type {@code org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type}
+   */
+  public static final class Type extends
+      org.jetbrains.kotlin.protobuf.GeneratedMessageLite implements
+      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type)
+      TypeOrBuilder {
+    // Use Type.newBuilder() to construct.
+    private Type(org.jetbrains.kotlin.protobuf.GeneratedMessageLite.Builder builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private Type(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.ByteString.EMPTY;}
+
+    private static final Type defaultInstance;
+    public static Type getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public Type getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final org.jetbrains.kotlin.protobuf.ByteString unknownFields;
+    private Type(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      org.jetbrains.kotlin.protobuf.ByteString.Output unknownFieldsOutput =
+          org.jetbrains.kotlin.protobuf.ByteString.newOutput();
+      org.jetbrains.kotlin.protobuf.CodedOutputStream unknownFieldsCodedOutput =
+          org.jetbrains.kotlin.protobuf.CodedOutputStream.newInstance(
+              unknownFieldsOutput);
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFieldsCodedOutput,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              org.jetbrains.kotlin.protobuf.ByteString bs = input.readBytes();
+              bitField0_ |= 0x00000001;
+              renderedType_ = bs;
+              break;
+            }
+          }
+        }
+      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        try {
+          unknownFieldsCodedOutput.flush();
+        } catch (java.io.IOException e) {
+        // Should not happen
+        } finally {
+          unknownFields = unknownFieldsOutput.toByteString();
+        }
+        makeExtensionsImmutable();
+      }
+    }
+    public static org.jetbrains.kotlin.protobuf.Parser<Type> PARSER =
+        new org.jetbrains.kotlin.protobuf.AbstractParser<Type>() {
+      public Type parsePartialFrom(
+          org.jetbrains.kotlin.protobuf.CodedInputStream input,
+          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+        return new Type(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public org.jetbrains.kotlin.protobuf.Parser<Type> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    public static final int RENDERED_TYPE_FIELD_NUMBER = 1;
+    private java.lang.Object renderedType_;
+    /**
+     * <code>optional string rendered_type = 1;</code>
+     *
+     * <pre>
+     * TODO: stub
+     * </pre>
+     */
+    public boolean hasRenderedType() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>optional string rendered_type = 1;</code>
+     *
+     * <pre>
+     * TODO: stub
+     * </pre>
+     */
+    public java.lang.String getRenderedType() {
+      java.lang.Object ref = renderedType_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        org.jetbrains.kotlin.protobuf.ByteString bs = 
+            (org.jetbrains.kotlin.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          renderedType_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>optional string rendered_type = 1;</code>
+     *
+     * <pre>
+     * TODO: stub
+     * </pre>
+     */
+    public org.jetbrains.kotlin.protobuf.ByteString
+        getRenderedTypeBytes() {
+      java.lang.Object ref = renderedType_;
+      if (ref instanceof java.lang.String) {
+        org.jetbrains.kotlin.protobuf.ByteString b = 
+            org.jetbrains.kotlin.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        renderedType_ = b;
+        return b;
+      } else {
+        return (org.jetbrains.kotlin.protobuf.ByteString) ref;
+      }
+    }
+
+    private void initFields() {
+      renderedType_ = "";
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBytes(1, getRenderedTypeBytes());
+      }
+      output.writeRawBytes(unknownFields);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
+          .computeBytesSize(1, getRenderedTypeBytes());
+      }
+      size += unknownFields.size();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type parseFrom(
+        org.jetbrains.kotlin.protobuf.ByteString data)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type parseFrom(
+        org.jetbrains.kotlin.protobuf.ByteString data,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type parseFrom(byte[] data)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type parseFrom(
+        byte[] data,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type parseFrom(
+        java.io.InputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type parseDelimitedFrom(
+        java.io.InputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type parseFrom(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type parseFrom(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    /**
+     * Protobuf type {@code org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type}
+     */
+    public static final class Builder extends
+        org.jetbrains.kotlin.protobuf.GeneratedMessageLite.Builder<
+          org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type, Builder>
+        implements
+        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type)
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.TypeOrBuilder {
+      // Construct using org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private void maybeForceBuilderInitialization() {
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        renderedType_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type getDefaultInstanceForType() {
+        return org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type.getDefaultInstance();
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type build() {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type buildPartial() {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type result = new org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.renderedType_ = renderedType_;
+        result.bitField0_ = to_bitField0_;
+        return result;
+      }
+
+      public Builder mergeFrom(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type other) {
+        if (other == org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type.getDefaultInstance()) return this;
+        if (other.hasRenderedType()) {
+          bitField0_ |= 0x00000001;
+          renderedType_ = other.renderedType_;
+          
+        }
+        setUnknownFields(
+            getUnknownFields().concat(other.unknownFields));
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          org.jetbrains.kotlin.protobuf.CodedInputStream input,
+          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.Type) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      private java.lang.Object renderedType_ = "";
+      /**
+       * <code>optional string rendered_type = 1;</code>
+       *
+       * <pre>
+       * TODO: stub
+       * </pre>
+       */
+      public boolean hasRenderedType() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>optional string rendered_type = 1;</code>
+       *
+       * <pre>
+       * TODO: stub
+       * </pre>
+       */
+      public java.lang.String getRenderedType() {
+        java.lang.Object ref = renderedType_;
+        if (!(ref instanceof java.lang.String)) {
+          org.jetbrains.kotlin.protobuf.ByteString bs =
+              (org.jetbrains.kotlin.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          if (bs.isValidUtf8()) {
+            renderedType_ = s;
+          }
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string rendered_type = 1;</code>
+       *
+       * <pre>
+       * TODO: stub
+       * </pre>
+       */
+      public org.jetbrains.kotlin.protobuf.ByteString
+          getRenderedTypeBytes() {
+        java.lang.Object ref = renderedType_;
+        if (ref instanceof String) {
+          org.jetbrains.kotlin.protobuf.ByteString b = 
+              org.jetbrains.kotlin.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          renderedType_ = b;
+          return b;
+        } else {
+          return (org.jetbrains.kotlin.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string rendered_type = 1;</code>
+       *
+       * <pre>
+       * TODO: stub
+       * </pre>
+       */
+      public Builder setRenderedType(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        renderedType_ = value;
+        
+        return this;
+      }
+      /**
+       * <code>optional string rendered_type = 1;</code>
+       *
+       * <pre>
+       * TODO: stub
+       * </pre>
+       */
+      public Builder clearRenderedType() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        renderedType_ = getDefaultInstance().getRenderedType();
+        
+        return this;
+      }
+      /**
+       * <code>optional string rendered_type = 1;</code>
+       *
+       * <pre>
+       * TODO: stub
+       * </pre>
+       */
+      public Builder setRenderedTypeBytes(
+          org.jetbrains.kotlin.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        renderedType_ = value;
+        
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type)
+    }
+
+    static {
+      defaultInstance = new Type(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.cli.jvm.compiler.tmp.Type)
+  }
+
+  public interface FileOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.cli.jvm.compiler.tmp.File)
+      org.jetbrains.kotlin.protobuf.MessageLiteOrBuilder {
+
+    /**
+     * <code>optional string relative_path = 1;</code>
+     */
+    boolean hasRelativePath();
+    /**
+     * <code>optional string relative_path = 1;</code>
+     */
+    java.lang.String getRelativePath();
+    /**
+     * <code>optional string relative_path = 1;</code>
+     */
+    org.jetbrains.kotlin.protobuf.ByteString
+        getRelativePathBytes();
+  }
+  /**
+   * Protobuf type {@code org.jetbrains.kotlin.cli.jvm.compiler.tmp.File}
+   */
+  public static final class File extends
+      org.jetbrains.kotlin.protobuf.GeneratedMessageLite implements
+      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.cli.jvm.compiler.tmp.File)
+      FileOrBuilder {
+    // Use File.newBuilder() to construct.
+    private File(org.jetbrains.kotlin.protobuf.GeneratedMessageLite.Builder builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private File(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.ByteString.EMPTY;}
+
+    private static final File defaultInstance;
+    public static File getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public File getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final org.jetbrains.kotlin.protobuf.ByteString unknownFields;
+    private File(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      org.jetbrains.kotlin.protobuf.ByteString.Output unknownFieldsOutput =
+          org.jetbrains.kotlin.protobuf.ByteString.newOutput();
+      org.jetbrains.kotlin.protobuf.CodedOutputStream unknownFieldsCodedOutput =
+          org.jetbrains.kotlin.protobuf.CodedOutputStream.newInstance(
+              unknownFieldsOutput);
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFieldsCodedOutput,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              org.jetbrains.kotlin.protobuf.ByteString bs = input.readBytes();
+              bitField0_ |= 0x00000001;
+              relativePath_ = bs;
+              break;
+            }
+          }
+        }
+      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        try {
+          unknownFieldsCodedOutput.flush();
+        } catch (java.io.IOException e) {
+        // Should not happen
+        } finally {
+          unknownFields = unknownFieldsOutput.toByteString();
+        }
+        makeExtensionsImmutable();
+      }
+    }
+    public static org.jetbrains.kotlin.protobuf.Parser<File> PARSER =
+        new org.jetbrains.kotlin.protobuf.AbstractParser<File>() {
+      public File parsePartialFrom(
+          org.jetbrains.kotlin.protobuf.CodedInputStream input,
+          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+        return new File(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public org.jetbrains.kotlin.protobuf.Parser<File> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    public static final int RELATIVE_PATH_FIELD_NUMBER = 1;
+    private java.lang.Object relativePath_;
+    /**
+     * <code>optional string relative_path = 1;</code>
+     */
+    public boolean hasRelativePath() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>optional string relative_path = 1;</code>
+     */
+    public java.lang.String getRelativePath() {
+      java.lang.Object ref = relativePath_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        org.jetbrains.kotlin.protobuf.ByteString bs = 
+            (org.jetbrains.kotlin.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          relativePath_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>optional string relative_path = 1;</code>
+     */
+    public org.jetbrains.kotlin.protobuf.ByteString
+        getRelativePathBytes() {
+      java.lang.Object ref = relativePath_;
+      if (ref instanceof java.lang.String) {
+        org.jetbrains.kotlin.protobuf.ByteString b = 
+            org.jetbrains.kotlin.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        relativePath_ = b;
+        return b;
+      } else {
+        return (org.jetbrains.kotlin.protobuf.ByteString) ref;
+      }
+    }
+
+    private void initFields() {
+      relativePath_ = "";
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBytes(1, getRelativePathBytes());
+      }
+      output.writeRawBytes(unknownFields);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
+          .computeBytesSize(1, getRelativePathBytes());
+      }
+      size += unknownFields.size();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File parseFrom(
+        org.jetbrains.kotlin.protobuf.ByteString data)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File parseFrom(
+        org.jetbrains.kotlin.protobuf.ByteString data,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File parseFrom(byte[] data)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File parseFrom(
+        byte[] data,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File parseFrom(
+        java.io.InputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File parseDelimitedFrom(
+        java.io.InputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File parseFrom(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File parseFrom(
+        org.jetbrains.kotlin.protobuf.CodedInputStream input,
+        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    /**
+     * Protobuf type {@code org.jetbrains.kotlin.cli.jvm.compiler.tmp.File}
+     */
+    public static final class Builder extends
+        org.jetbrains.kotlin.protobuf.GeneratedMessageLite.Builder<
+          org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File, Builder>
+        implements
+        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.cli.jvm.compiler.tmp.File)
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.FileOrBuilder {
+      // Construct using org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private void maybeForceBuilderInitialization() {
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        relativePath_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File getDefaultInstanceForType() {
+        return org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File.getDefaultInstance();
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File build() {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File buildPartial() {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File result = new org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.relativePath_ = relativePath_;
+        result.bitField0_ = to_bitField0_;
+        return result;
+      }
+
+      public Builder mergeFrom(org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File other) {
+        if (other == org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File.getDefaultInstance()) return this;
+        if (other.hasRelativePath()) {
+          bitField0_ |= 0x00000001;
+          relativePath_ = other.relativePath_;
+          
+        }
+        setUnknownFields(
+            getUnknownFields().concat(other.unknownFields));
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          org.jetbrains.kotlin.protobuf.CodedInputStream input,
+          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.jetbrains.kotlin.cli.jvm.compiler.tmp.ResolutionDumpProtoBuf.File) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      private java.lang.Object relativePath_ = "";
+      /**
+       * <code>optional string relative_path = 1;</code>
+       */
+      public boolean hasRelativePath() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>optional string relative_path = 1;</code>
+       */
+      public java.lang.String getRelativePath() {
+        java.lang.Object ref = relativePath_;
+        if (!(ref instanceof java.lang.String)) {
+          org.jetbrains.kotlin.protobuf.ByteString bs =
+              (org.jetbrains.kotlin.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          if (bs.isValidUtf8()) {
+            relativePath_ = s;
+          }
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string relative_path = 1;</code>
+       */
+      public org.jetbrains.kotlin.protobuf.ByteString
+          getRelativePathBytes() {
+        java.lang.Object ref = relativePath_;
+        if (ref instanceof String) {
+          org.jetbrains.kotlin.protobuf.ByteString b = 
+              org.jetbrains.kotlin.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          relativePath_ = b;
+          return b;
+        } else {
+          return (org.jetbrains.kotlin.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string relative_path = 1;</code>
+       */
+      public Builder setRelativePath(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        relativePath_ = value;
+        
+        return this;
+      }
+      /**
+       * <code>optional string relative_path = 1;</code>
+       */
+      public Builder clearRelativePath() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        relativePath_ = getDefaultInstance().getRelativePath();
+        
+        return this;
+      }
+      /**
+       * <code>optional string relative_path = 1;</code>
+       */
+      public Builder setRelativePathBytes(
+          org.jetbrains.kotlin.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        relativePath_ = value;
+        
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.cli.jvm.compiler.tmp.File)
+    }
+
+    static {
+      defaultInstance = new File(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.cli.jvm.compiler.tmp.File)
+  }
+
+
+  static {
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/ResolutionDumpSerializer.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/ResolutionDumpSerializer.kt
new file mode 100644
index 0000000..b3f4291
--- /dev/null
+++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/ResolutionDumpSerializer.kt
@@ -0,0 +1,86 @@
+/*
+ * 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/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.cli.jvm.compiler.tmp
+
+import org.jetbrains.kotlin.cli.jvm.compiler.tmp.impls.*
+
+interface ResolutionDumpSerializer {
+    fun serialize(dumpForFile: RDumpForFile): ByteArray
+}
+
+class ProtoBufResolutionDumpSerializer : ResolutionDumpSerializer {
+    override fun serialize(dumpForFile: RDumpForFile): ByteArray {
+        return resolutionResultsForFileProto(dumpForFile).build().toByteArray()
+    }
+
+    private fun resolutionResultsForFileProto(dumpForFile: RDumpForFile): ResolutionDumpProtoBuf.ResolutionResultForFile.Builder {
+        return ResolutionDumpProtoBuf.ResolutionResultForFile.newBuilder().apply {
+            file = ResolutionDumpProtoBuf.File.newBuilder().setRelativePath(dumpForFile.ownerFile.pathRelativeToRoot).build()
+
+            for (rDumpElement in dumpForFile.results) {
+                val elementBuilder = ResolutionDumpProtoBuf.Element.newBuilder()
+                elementBuilder.offset = rDumpElement.offset
+                elementBuilder.presentableText = rDumpElement.presentableText
+
+                when (rDumpElement) {
+                    is RDumpExpression ->
+                        elementBuilder.expression = expressionProto(rDumpElement).build()
+
+                    else -> throw IllegalStateException("Unknown Element type: $rDumpElement")
+                }
+
+                addElement(elementBuilder.build())
+            }
+        }
+    }
+
+    private fun expressionProto(expression: RDumpExpression): ResolutionDumpProtoBuf.Expression.Builder {
+        return ResolutionDumpProtoBuf.Expression.newBuilder().apply {
+            type = typeProto(expression.type).build()
+
+            when (expression) {
+                is RDumpResolvedCall -> resolved = resolvedProto(expression).build()
+                is RDumpErrorCall -> error = errorProto(expression).build()
+                else -> throw IllegalStateException("Unknown Expression type: $expression")
+            }
+        }
+    }
+
+    private fun resolvedProto(resolved: RDumpResolvedCall): ResolutionDumpProtoBuf.Resolved.Builder {
+        val candidateDescriptorProto = descriptorProto(resolved.candidateDescriptor).build()
+        val typeArgumentsProtos = resolved.typeArguments.map { typeProto(it).build() }
+
+        return ResolutionDumpProtoBuf.Resolved.newBuilder()
+            .setCandidateDescriptor(candidateDescriptorProto)
+            .addAllTypeArgument(typeArgumentsProtos)
+    }
+
+    private fun errorProto(error: RDumpErrorCall): ResolutionDumpProtoBuf.Error.Builder {
+        return ResolutionDumpProtoBuf.Error.newBuilder().apply {
+            for (diagnostic in error.diagnostics) {
+                addDiagnostic(diagnosticProto(diagnostic))
+            }
+        }
+    }
+
+    private fun diagnosticProto(rDumpDiagnostic: RDumpDiagnostic): ResolutionDumpProtoBuf.Diagnostic.Builder {
+        val textBasedRDumpDiagnostic = rDumpDiagnostic as TextBasedRDumpDiagnostic
+        return ResolutionDumpProtoBuf.Diagnostic.newBuilder().setRenderedText(textBasedRDumpDiagnostic.fullRenderedText)
+    }
+
+    private fun descriptorProto(rDumpDescriptor: RDumpDescriptor): ResolutionDumpProtoBuf.Descriptor.Builder {
+        return ResolutionDumpProtoBuf.Descriptor.newBuilder().apply {
+            fqn = (rDumpDescriptor as? TextBasedRDumpDescriptor)?.renderedDescriptor
+
+            for (typeParameterDescriptor in rDumpDescriptor.typeParameters) {
+                addTypeParameter(descriptorProto(typeParameterDescriptor).build())
+            }
+        }
+    }
+
+    private fun typeProto(rDumpType: RDumpType): ResolutionDumpProtoBuf.Type.Builder =
+        ResolutionDumpProtoBuf.Type.newBuilder().setRenderedType((rDumpType as TextBasedRDumpType).renderedType)
+}
\ No newline at end of file
diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/ResolutionDumper.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/ResolutionDumper.kt
new file mode 100644
index 0000000..5fb0b33
--- /dev/null
+++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/ResolutionDumper.kt
@@ -0,0 +1,29 @@
+/*
+ * 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/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.cli.jvm.compiler.tmp
+
+import java.io.File
+
+interface ResolutionDumper {
+    fun dumpResolutionResult(dumpForFile: RDumpForFile)
+}
+
+class ResolutionDumperImpl(private val serializer: ResolutionDumpSerializer, private val root: File) : ResolutionDumper {
+    override fun dumpResolutionResult(dumpForFile: RDumpForFile) {
+        val destinationFile = File(root, dumpForFile.ownerFile.pathRelativeToRoot)
+        if (destinationFile.exists()) {
+            destinationFile.delete()
+        }
+
+        destinationFile.createNewFile()
+
+        val serializedResolutionResult = serializer.serialize(dumpForFile)
+
+        destinationFile.outputStream().use {
+            it.write(serializedResolutionResult)
+        }
+    }
+}
\ No newline at end of file
diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/ResolutionDumpsComparator.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/ResolutionDumpsComparator.kt
new file mode 100644
index 0000000..aaeb725
--- /dev/null
+++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/ResolutionDumpsComparator.kt
@@ -0,0 +1,193 @@
+/*
+ * 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/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.cli.jvm.compiler.tmp
+
+import org.jetbrains.kotlin.cli.jvm.compiler.tmp.impls.RDumpErrorCall
+import org.jetbrains.kotlin.cli.jvm.compiler.tmp.impls.RDumpResolvedCall
+import org.jetbrains.kotlin.utils.addIfNotNull
+
+class ResolutionDumpsComparator {
+    fun compareDumpsForFile(before: RDumpForFile, after: RDumpForFile) {
+        check(before.ownerFile == after.ownerFile) { "Trying to compare dumps for different files" }
+
+        val offsetToElementMapBefore = before.results.associateBy { it.offset }
+        val offsetToElementMapAfter = after.results.associateBy { it.offset }
+
+        val allOffsets = offsetToElementMapBefore.keys union offsetToElementMapAfter.keys
+
+        val diff: MutableList<ResolutionDifference> = mutableListOf()
+        for (offset in allOffsets) {
+            val elementBefore = offsetToElementMapBefore[offset]
+            val elementAfter = offsetToElementMapAfter[offset]
+
+            val difference = when {
+                elementBefore != null && elementAfter == null ->
+                    ResolutionDifference(elementBefore.presentableText, MissingInDump(elementBefore, elementAfter))
+
+                elementBefore == null && elementAfter != null ->
+                    ResolutionDifference(elementAfter.presentableText, MissingInDump(elementBefore, elementAfter))
+
+                elementBefore != null && elementAfter != null -> compareResolutionElements(elementBefore, elementAfter)
+
+                else -> throw IllegalStateException("No elements at offset $offset")
+            }
+
+            diff.addIfNotNull(difference)
+        }
+    }
+
+    private fun compareResolutionElements(before: RDumpElement, after: RDumpElement): ResolutionDifference? {
+        check(before.presentableText == after.presentableText) {
+            "Elements at the same offsets in the same file have different presentable texts:\n" +
+                    "   First: $before\n" +
+                    "   Second: $after"
+        }
+
+        if (before::class != after::class) {
+            return ResolutionDifference(before.presentableText, ResolutionStatusMismatch(before, after))
+        }
+
+        return when {
+            before is RDumpExpression && after is RDumpExpression -> compareExpressions(before, after)
+            else -> throw IllegalStateException("Unknown Element type: $before")
+        }
+    }
+
+    private fun compareExpressions(before: RDumpExpression, after: RDumpExpression): ResolutionDifference? {
+        return when {
+            before is RDumpResolvedCall && after is RDumpResolvedCall -> compareResolved(before, after)
+            before is RDumpErrorCall && after is RDumpErrorCall -> compareErrorCalls(before, after)
+            else -> throw IllegalStateException("Unknown Expression type: $before")
+        }
+    }
+
+    private fun compareErrorCalls(before: RDumpErrorCall, after: RDumpErrorCall): ResolutionDifference? {
+        val diagnosticsSetBefore = before.diagnostics.toSet()
+        val diagnosticsSetAfter = after.diagnostics.toSet()
+
+        val allDiagnostics = diagnosticsSetBefore union diagnosticsSetAfter
+
+        val mismatchedDiagnostics: MutableList<DiagnosticsMismatch.MismatchedDiagnostic> = mutableListOf()
+        iterateOverDiagnostics@ for (diagnostic in allDiagnostics) {
+            when {
+                diagnostic in diagnosticsSetBefore && diagnostic in diagnosticsSetAfter ->
+                    continue@iterateOverDiagnostics
+
+                diagnostic in diagnosticsSetBefore && diagnostic !in diagnosticsSetAfter ->
+                    mismatchedDiagnostics += DiagnosticsMismatch.LostDiagnostic(diagnostic)
+
+                diagnostic !in diagnosticsSetBefore && diagnostic in diagnosticsSetAfter ->
+                    mismatchedDiagnostics += DiagnosticsMismatch.NewDiagnostic(diagnostic)
+
+                else -> throw IllegalStateException()
+            }
+        }
+
+        return if (mismatchedDiagnostics.isNotEmpty())
+            ResolutionDifference(before.presentableText, DiagnosticsMismatch(mismatchedDiagnostics))
+        else
+            null
+    }
+
+    private fun compareResolved(before: RDumpResolvedCall, after: RDumpResolvedCall): ResolutionDifference? {
+        if (before.candidateDescriptor != after.candidateDescriptor) {
+            return ResolutionDifference(
+                before.presentableText,
+                CandidateDescriptorMismatch(before.candidateDescriptor, after.candidateDescriptor)
+            )
+        }
+
+        val typeParameterDifferences: MutableList<InferenceMismatch.TypeParameterInference> = mutableListOf()
+        for (i in before.candidateDescriptor.typeParameters.indices) {
+            val typeParameterBefore = before.candidateDescriptor.typeParameters[i]
+            val typeParameterAfter = after.candidateDescriptor.typeParameters[i]
+            check(typeParameterBefore == typeParameterAfter) {
+                "Type parameters in candidate descriptors are not the same: for index $i before was $typeParameterBefore, after became $typeParameterAfter"
+            }
+
+            val typeArgumentBefore = before.typeArguments[i]
+            val typeArgumentAfter = after.typeArguments[i]
+
+            if (typeArgumentBefore != typeArgumentAfter) {
+                typeParameterDifferences.add(
+                    InferenceMismatch.TypeParameterInference(
+                        typeParameterBefore,
+                        typeArgumentBefore,
+                        typeArgumentAfter
+                    )
+                )
+            }
+        }
+
+        return if (typeParameterDifferences.isNotEmpty())
+            ResolutionDifference(before.presentableText, InferenceMismatch(typeParameterDifferences))
+        else
+            null
+    }
+
+}
+
+
+class ResolutionDifference(val elementText: String, val reason: MismatchReason) {
+    fun render(): String =
+        "Resolution mismatch for $elementText\n" + reason.reasonText
+}
+
+
+sealed class MismatchReason(val reasonText: String)
+
+class MissingInDump(before: RDumpElement?, after: RDumpElement?) :
+    MismatchReason(
+        "Missing resolution result in one of the dumps:\n" +
+                "    Was: ${before ?: "<ABSENT>"}\n" +
+                "    Become: ${after ?: "<ABSENT>"}\n"
+    )
+
+class CandidateDescriptorMismatch(beforeDescriptor: RDumpDescriptor, afterDescriptor: RDumpDescriptor) :
+    MismatchReason(
+        "Candidate descriptor have changed:\n" +
+                "   Was: $beforeDescriptor\n" +
+                "   Become: $afterDescriptor"
+    )
+
+class InferenceMismatch(val mismatchedTypeParameters: List<TypeParameterInference>) :
+    MismatchReason(
+        "Inference for type parameter(s) have changed:\n" +
+                mismatchedTypeParameters.joinToString(separator = "\n\n")
+    ) {
+
+    data class TypeParameterInference(val typeParameterDescriptor: RDumpDescriptor, val before: RDumpType, val after: RDumpType) {
+        override fun toString(): String = "Type parameter: $typeParameterDescriptor\n" +
+                "Was: $before\n" +
+                "Become: $after"
+    }
+}
+
+
+// E.g. Resolved -> Error
+class ResolutionStatusMismatch(before: RDumpElement, after: RDumpElement) :
+    MismatchReason(
+        "Resolution kind have changed:" +
+                "   Was: $before\n" +
+                "   After: $after"
+    )
+
+class DiagnosticsMismatch(mismatchedDiagnostics: List<MismatchedDiagnostic>) :
+    MismatchReason("Diagnostics are different:\n" + mismatchedDiagnostics.joinToString(separator = "\n")) {
+
+    interface MismatchedDiagnostic
+
+    class NewDiagnostic(val diagnostic: RDumpDiagnostic) : MismatchedDiagnostic {
+        override fun toString(): String = "Appeared new diagnostic: \"$diagnostic\""
+    }
+
+    class LostDiagnostic(val diagnostic: RDumpDiagnostic) : MismatchedDiagnostic {
+        override fun toString(): String = "Missing diagnostic: \"$diagnostic\""
+    }
+}
+
+
+
diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/ResolutionResults.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/ResolutionResults.kt
new file mode 100644
index 0000000..97a46b7
--- /dev/null
+++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/ResolutionResults.kt
@@ -0,0 +1,41 @@
+/*
+ * 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/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.cli.jvm.compiler.tmp
+
+class RDumpForFile(val ownerFile: RDumpFile, val results: List<RDumpElement>)
+
+
+// ====== Hierarchy ==========
+
+interface RDumpElement {
+    val offset: Int
+    val presentableText: String
+}
+
+interface RDumpExpression : RDumpElement {
+    val type: RDumpType
+}
+
+
+// ======== Utility =============
+
+interface RDumpFile {
+    val pathRelativeToRoot: String
+
+    fun getLineNumberByOffset(offset: Int): Int
+    fun getColumnNumberByOffset(offset: Int): Int
+}
+
+// TODO: full descriptor?
+interface RDumpDescriptor {
+    val typeParameters: List<RDumpDescriptor>
+}
+
+// TODO: full type?
+interface RDumpType
+
+// TODO: full diagnostic?
+interface RDumpDiagnostic
\ No newline at end of file
diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/impls/ResolutionDumpImpls.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/impls/ResolutionDumpImpls.kt
new file mode 100644
index 0000000..47a434b
--- /dev/null
+++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/impls/ResolutionDumpImpls.kt
@@ -0,0 +1,56 @@
+/*
+ * 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/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.cli.jvm.compiler.tmp.impls
+
+import org.jetbrains.kotlin.cli.jvm.compiler.tmp.*
+import org.jetbrains.kotlin.psi.KtElement
+import org.jetbrains.kotlin.psi.psiUtil.startOffset
+
+// Equality expected to work correctly only with elements from the same file
+abstract class AbstractRDumpElement(override val offset: Int, override val presentableText: String) : RDumpElement {
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (javaClass != other?.javaClass) return false
+
+        other as AbstractRDumpElement
+
+        if (offset != other.offset) return false
+
+        return true
+    }
+
+    override fun hashCode(): Int = offset
+
+    override fun toString(): String = presentableText
+}
+
+abstract class AbstractRDumpExpression(offset: Int, presentableText: String, override val type: RDumpType) :
+    AbstractRDumpElement(offset, presentableText), RDumpExpression
+
+class RDumpResolvedCall(
+    offset: Int,
+    presentableText: String,
+    type: RDumpType,
+    val candidateDescriptor: RDumpDescriptor,
+    val typeArguments: List<RDumpType>
+) : AbstractRDumpExpression(offset, presentableText, type) {
+
+    constructor(
+        original: KtElement,
+        type: RDumpType,
+        candidateDescriptor: RDumpDescriptor,
+        typeArguments: List<RDumpType>
+    ) : this(original.startOffset, original.text, type, candidateDescriptor, typeArguments)
+}
+
+class RDumpErrorCall(offset: Int, presentableText: String, val diagnostics: List<RDumpDiagnostic>) :
+    AbstractRDumpExpression(offset, presentableText, RDumpErrorType) {
+
+    constructor(
+        original: KtElement,
+        vararg diagnostics: RDumpDiagnostic
+    ) : this(original.startOffset, original.text, diagnostics.toList())
+}
diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/impls/TextBasedStubs.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/impls/TextBasedStubs.kt
new file mode 100644
index 0000000..50f0d19
--- /dev/null
+++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/impls/TextBasedStubs.kt
@@ -0,0 +1,54 @@
+/*
+ * 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/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.cli.jvm.compiler.tmp.impls
+
+import org.jetbrains.kotlin.cli.jvm.compiler.tmp.NativeElementsFactory
+import org.jetbrains.kotlin.cli.jvm.compiler.tmp.RDumpDescriptor
+import org.jetbrains.kotlin.cli.jvm.compiler.tmp.RDumpDiagnostic
+import org.jetbrains.kotlin.cli.jvm.compiler.tmp.RDumpType
+import org.jetbrains.kotlin.descriptors.CallableDescriptor
+import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
+import org.jetbrains.kotlin.diagnostics.Diagnostic
+import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
+import org.jetbrains.kotlin.renderer.DescriptorRenderer
+import org.jetbrains.kotlin.types.KotlinType
+
+open class TextBasedRDumpType(val renderedType: String) : RDumpType
+object RDumpErrorType : TextBasedRDumpType("ERROR_TYPE")
+
+open class TextBasedRDumpDescriptor(val renderedDescriptor: String, override val typeParameters: List<RDumpDescriptor>) : RDumpDescriptor
+
+class TextBasedRDumpDiagnostic(val diagnosticFamily: String, val fullRenderedText: String) : RDumpDiagnostic
+
+object TextBasedNativeElementsFactory : NativeElementsFactory {
+    override fun convertToRDumpDescriptor(descriptor: DeclarationDescriptor): RDumpDescriptor {
+        val typeParameters = (descriptor as? CallableDescriptor)?.typeParameters?.map { convertToRDumpDescriptor(it) } ?: emptyList()
+        return TextBasedRDumpDescriptor(renderDescriptor(descriptor), typeParameters)
+    }
+
+    override fun convertToRDumpType(type: KotlinType): RDumpType {
+        return TextBasedRDumpType(renderType(type))
+    }
+
+    override fun convertToRDumpDiagnostic(diagnostic: Diagnostic): RDumpDiagnostic {
+        return TextBasedRDumpDiagnostic(
+            diagnosticFamily = diagnostic.factory.name,
+            fullRenderedText = renderDiagnostic(diagnostic)
+        )
+    }
+
+    private fun renderDescriptor(descriptor: DeclarationDescriptor): String {
+        return DescriptorRenderer.DEBUG_TEXT.render(descriptor)
+    }
+
+    private fun renderType(type: KotlinType): String {
+        return DescriptorRenderer.DEBUG_TEXT.renderType(type)
+    }
+
+    private fun renderDiagnostic(diagnostic: Diagnostic): String {
+        return DefaultErrorMessages.render(diagnostic)
+    }
+}
\ No newline at end of file
diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/impls/VirtualFileBasedRDumpFile.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/impls/VirtualFileBasedRDumpFile.kt
new file mode 100644
index 0000000..932ceb1
--- /dev/null
+++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/tmp/impls/VirtualFileBasedRDumpFile.kt
@@ -0,0 +1,34 @@
+/*
+ * 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/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.cli.jvm.compiler.tmp.impls
+
+import org.jetbrains.kotlin.cli.jvm.compiler.tmp.RDumpFile
+import java.io.File
+
+class FileBasedRDumpFile(val file: File, override val pathRelativeToRoot: String) : RDumpFile {
+    override fun getLineNumberByOffset(offset: Int): Int {
+        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+    }
+
+    override fun getColumnNumberByOffset(offset: Int): Int {
+        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+    }
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (javaClass != other?.javaClass) return false
+
+        other as FileBasedRDumpFile
+
+        if (pathRelativeToRoot != other.pathRelativeToRoot) return false
+
+        return true
+    }
+
+    override fun hashCode(): Int {
+        return pathRelativeToRoot.hashCode()
+    }
+}
\ No newline at end of file
diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractResolutionDumpTest.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractResolutionDumpTest.kt
new file mode 100644
index 0000000..75e5355
--- /dev/null
+++ b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractResolutionDumpTest.kt
@@ -0,0 +1,33 @@
+/*
+ * 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/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.codegen
+
+import org.jetbrains.kotlin.cli.jvm.compiler.tmp.IrBasedResolutionDumpBuilder
+import org.jetbrains.kotlin.cli.jvm.compiler.tmp.impls.TextBasedNativeElementsFactory
+import org.jetbrains.kotlin.config.LanguageVersionSettings
+import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
+import org.jetbrains.kotlin.ir.AbstractIrGeneratorTestCase
+import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
+import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
+import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
+import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil
+import java.io.File
+
+class AbstractResolutionDumpTest : AbstractIrGeneratorTestCase() {
+    override fun doTest(wholeFile: File, testFiles: List<TestFile>) {
+        val (bindingContext, moduleDescriptor, _) = JvmResolveUtil.analyze(myFiles.psiFiles, myEnvironment)
+        val generatorContext = GeneratorContext(Psi2IrConfiguration(ignoreErrors = true), moduleDescriptor, bindingContext)
+        val psi2ir = Psi2IrTranslator(LanguageVersionSettingsImpl.DEFAULT)
+        val builder = IrBasedResolutionDumpBuilder(bindingContext, TextBasedNativeElementsFactory, File(""))
+
+        val moduleFragment = psi2ir.generateModuleFragment(generatorContext, myFiles.psiFiles)
+
+        for (irFile in moduleFragment.files) {
+            val physicalFile = File(irFile.fileEntry.name)
+            builder.buildResolutionDumpForFile(irFile, physicalFile)
+        }
+    }
+}
\ No newline at end of file
