Internal change

PiperOrigin-RevId: 383873010
Change-Id: Iea5806e6603f3af9c581dda0931afa18190de28f
diff --git a/java/org/eclipse/lsp4j/AbstractTextDocumentRegistrationAndWorkDoneProgressOptions.java b/java/org/eclipse/lsp4j/AbstractTextDocumentRegistrationAndWorkDoneProgressOptions.java
new file mode 100644
index 0000000..bf5de50
--- /dev/null
+++ b/java/org/eclipse/lsp4j/AbstractTextDocumentRegistrationAndWorkDoneProgressOptions.java
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.DocumentFilter;
+import org.eclipse.lsp4j.TextDocumentRegistrationOptions;
+import org.eclipse.lsp4j.WorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Options to signal work done progress support in server capabilities and TextDocumentRegistrationOptions.
+ * It is not present in protocol specification, so it's just "dry" class.
+ * <p>
+ * Since 3.15.0
+ */
+@SuppressWarnings("all")
+public abstract class AbstractTextDocumentRegistrationAndWorkDoneProgressOptions extends TextDocumentRegistrationOptions implements WorkDoneProgressOptions {
+  private Boolean workDoneProgress;
+  
+  public AbstractTextDocumentRegistrationAndWorkDoneProgressOptions() {
+  }
+  
+  public AbstractTextDocumentRegistrationAndWorkDoneProgressOptions(final List<DocumentFilter> documentSelector) {
+    super(documentSelector);
+  }
+  
+  @Pure
+  @Override
+  public Boolean getWorkDoneProgress() {
+    return this.workDoneProgress;
+  }
+  
+  public void setWorkDoneProgress(final Boolean workDoneProgress) {
+    this.workDoneProgress = workDoneProgress;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneProgress", this.workDoneProgress);
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    AbstractTextDocumentRegistrationAndWorkDoneProgressOptions other = (AbstractTextDocumentRegistrationAndWorkDoneProgressOptions) obj;
+    if (this.workDoneProgress == null) {
+      if (other.workDoneProgress != null)
+        return false;
+    } else if (!this.workDoneProgress.equals(other.workDoneProgress))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.workDoneProgress== null) ? 0 : this.workDoneProgress.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/AbstractWorkDoneProgressOptions.java b/java/org/eclipse/lsp4j/AbstractWorkDoneProgressOptions.java
new file mode 100644
index 0000000..f32ff60
--- /dev/null
+++ b/java/org/eclipse/lsp4j/AbstractWorkDoneProgressOptions.java
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.WorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Options to signal work done progress support in server capabilities.
+ * It is not present in protocol specification, so it's just "dry" class.
+ * <p>
+ * Since 3.15.0
+ */
+@SuppressWarnings("all")
+public abstract class AbstractWorkDoneProgressOptions implements WorkDoneProgressOptions {
+  private Boolean workDoneProgress;
+  
+  @Pure
+  @Override
+  public Boolean getWorkDoneProgress() {
+    return this.workDoneProgress;
+  }
+  
+  public void setWorkDoneProgress(final Boolean workDoneProgress) {
+    this.workDoneProgress = workDoneProgress;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneProgress", this.workDoneProgress);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    AbstractWorkDoneProgressOptions other = (AbstractWorkDoneProgressOptions) obj;
+    if (this.workDoneProgress == null) {
+      if (other.workDoneProgress != null)
+        return false;
+    } else if (!this.workDoneProgress.equals(other.workDoneProgress))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.workDoneProgress== null) ? 0 : this.workDoneProgress.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/AnnotatedTextEdit.java b/java/org/eclipse/lsp4j/AnnotatedTextEdit.java
new file mode 100644
index 0000000..89f3e1f
--- /dev/null
+++ b/java/org/eclipse/lsp4j/AnnotatedTextEdit.java
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.TextEdit;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A special text edit with an additional change annotation.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class AnnotatedTextEdit extends TextEdit {
+  /**
+   * The actual annotation identifier
+   */
+  @NonNull
+  private String annotationId;
+  
+  public AnnotatedTextEdit() {
+  }
+  
+  public AnnotatedTextEdit(@NonNull final Range range, @NonNull final String newText, @NonNull final String annotationId) {
+    super(range, newText);
+    this.annotationId = Preconditions.<String>checkNotNull(annotationId, "annotationId");
+  }
+  
+  /**
+   * The actual annotation identifier
+   */
+  @Pure
+  @NonNull
+  public String getAnnotationId() {
+    return this.annotationId;
+  }
+  
+  /**
+   * The actual annotation identifier
+   */
+  public void setAnnotationId(@NonNull final String annotationId) {
+    this.annotationId = Preconditions.checkNotNull(annotationId, "annotationId");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("annotationId", this.annotationId);
+    b.add("range", getRange());
+    b.add("newText", getNewText());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    AnnotatedTextEdit other = (AnnotatedTextEdit) obj;
+    if (this.annotationId == null) {
+      if (other.annotationId != null)
+        return false;
+    } else if (!this.annotationId.equals(other.annotationId))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.annotationId== null) ? 0 : this.annotationId.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ApplyWorkspaceEditParams.java b/java/org/eclipse/lsp4j/ApplyWorkspaceEditParams.java
new file mode 100644
index 0000000..8396542
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ApplyWorkspaceEditParams.java
@@ -0,0 +1,125 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.WorkspaceEdit;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The workspace/applyEdit request is sent from the server to the client to modify resource on the client side.
+ */
+@SuppressWarnings("all")
+public class ApplyWorkspaceEditParams {
+  /**
+   * The edits to apply.
+   */
+  @NonNull
+  private WorkspaceEdit edit;
+  
+  /**
+   * An optional label of the workspace edit. This label is
+   * presented in the user interface for example on an undo
+   * stack to undo the workspace edit.
+   */
+  private String label;
+  
+  public ApplyWorkspaceEditParams() {
+  }
+  
+  public ApplyWorkspaceEditParams(@NonNull final WorkspaceEdit edit) {
+    this.edit = Preconditions.<WorkspaceEdit>checkNotNull(edit, "edit");
+  }
+  
+  public ApplyWorkspaceEditParams(@NonNull final WorkspaceEdit edit, final String label) {
+    this(edit);
+    this.label = label;
+  }
+  
+  /**
+   * The edits to apply.
+   */
+  @Pure
+  @NonNull
+  public WorkspaceEdit getEdit() {
+    return this.edit;
+  }
+  
+  /**
+   * The edits to apply.
+   */
+  public void setEdit(@NonNull final WorkspaceEdit edit) {
+    this.edit = Preconditions.checkNotNull(edit, "edit");
+  }
+  
+  /**
+   * An optional label of the workspace edit. This label is
+   * presented in the user interface for example on an undo
+   * stack to undo the workspace edit.
+   */
+  @Pure
+  public String getLabel() {
+    return this.label;
+  }
+  
+  /**
+   * An optional label of the workspace edit. This label is
+   * presented in the user interface for example on an undo
+   * stack to undo the workspace edit.
+   */
+  public void setLabel(final String label) {
+    this.label = label;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("edit", this.edit);
+    b.add("label", this.label);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ApplyWorkspaceEditParams other = (ApplyWorkspaceEditParams) obj;
+    if (this.edit == null) {
+      if (other.edit != null)
+        return false;
+    } else if (!this.edit.equals(other.edit))
+      return false;
+    if (this.label == null) {
+      if (other.label != null)
+        return false;
+    } else if (!this.label.equals(other.label))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.edit== null) ? 0 : this.edit.hashCode());
+    return prime * result + ((this.label== null) ? 0 : this.label.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ApplyWorkspaceEditResponse.java b/java/org/eclipse/lsp4j/ApplyWorkspaceEditResponse.java
new file mode 100644
index 0000000..134c195
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ApplyWorkspaceEditResponse.java
@@ -0,0 +1,145 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class ApplyWorkspaceEditResponse {
+  /**
+   * Indicates whether the edit was applied or not.
+   */
+  private boolean applied;
+  
+  /**
+   * An optional textual description for why the edit was not applied.
+   * This may be used by the server for diagnostic logging or to provide
+   * a suitable error for a request that triggered the edit.
+   */
+  private String failureReason;
+  
+  /**
+   * Depending on the client's failure handling strategy `failedChange`
+   * might contain the index of the change that failed. This property is
+   * only available if the client signals a {@link WorkspaceEditCapabilities#failureHandling}
+   * strategy in its client capabilities.
+   */
+  private Integer failedChange;
+  
+  public ApplyWorkspaceEditResponse() {
+  }
+  
+  public ApplyWorkspaceEditResponse(final boolean applied) {
+    this.applied = applied;
+  }
+  
+  /**
+   * Indicates whether the edit was applied or not.
+   */
+  @Pure
+  public boolean isApplied() {
+    return this.applied;
+  }
+  
+  /**
+   * Indicates whether the edit was applied or not.
+   */
+  public void setApplied(final boolean applied) {
+    this.applied = applied;
+  }
+  
+  /**
+   * An optional textual description for why the edit was not applied.
+   * This may be used by the server for diagnostic logging or to provide
+   * a suitable error for a request that triggered the edit.
+   */
+  @Pure
+  public String getFailureReason() {
+    return this.failureReason;
+  }
+  
+  /**
+   * An optional textual description for why the edit was not applied.
+   * This may be used by the server for diagnostic logging or to provide
+   * a suitable error for a request that triggered the edit.
+   */
+  public void setFailureReason(final String failureReason) {
+    this.failureReason = failureReason;
+  }
+  
+  /**
+   * Depending on the client's failure handling strategy `failedChange`
+   * might contain the index of the change that failed. This property is
+   * only available if the client signals a {@link WorkspaceEditCapabilities#failureHandling}
+   * strategy in its client capabilities.
+   */
+  @Pure
+  public Integer getFailedChange() {
+    return this.failedChange;
+  }
+  
+  /**
+   * Depending on the client's failure handling strategy `failedChange`
+   * might contain the index of the change that failed. This property is
+   * only available if the client signals a {@link WorkspaceEditCapabilities#failureHandling}
+   * strategy in its client capabilities.
+   */
+  public void setFailedChange(final Integer failedChange) {
+    this.failedChange = failedChange;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("applied", this.applied);
+    b.add("failureReason", this.failureReason);
+    b.add("failedChange", this.failedChange);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ApplyWorkspaceEditResponse other = (ApplyWorkspaceEditResponse) obj;
+    if (other.applied != this.applied)
+      return false;
+    if (this.failureReason == null) {
+      if (other.failureReason != null)
+        return false;
+    } else if (!this.failureReason.equals(other.failureReason))
+      return false;
+    if (this.failedChange == null) {
+      if (other.failedChange != null)
+        return false;
+    } else if (!this.failedChange.equals(other.failedChange))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + (this.applied ? 1231 : 1237);
+    result = prime * result + ((this.failureReason== null) ? 0 : this.failureReason.hashCode());
+    return prime * result + ((this.failedChange== null) ? 0 : this.failedChange.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CallHierarchyCapabilities.java b/java/org/eclipse/lsp4j/CallHierarchyCapabilities.java
new file mode 100644
index 0000000..2044f67
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CallHierarchyCapabilities.java
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the {@code textDocument/prepareCallHierarchy}.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class CallHierarchyCapabilities extends DynamicRegistrationCapabilities {
+  public CallHierarchyCapabilities() {
+  }
+  
+  public CallHierarchyCapabilities(final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CallHierarchyIncomingCall.java b/java/org/eclipse/lsp4j/CallHierarchyIncomingCall.java
new file mode 100644
index 0000000..6067078
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CallHierarchyIncomingCall.java
@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.CallHierarchyItem;
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Represents an incoming call, e.g. a caller of a method or constructor.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class CallHierarchyIncomingCall {
+  /**
+   * The item that makes the call.
+   */
+  @NonNull
+  private CallHierarchyItem from;
+  
+  /**
+   * The range at which at which the calls appears. This is relative to the caller
+   * denoted by {@link #from}.
+   */
+  @NonNull
+  private List<Range> fromRanges;
+  
+  public CallHierarchyIncomingCall() {
+  }
+  
+  public CallHierarchyIncomingCall(@NonNull final CallHierarchyItem from, @NonNull final List<Range> fromRanges) {
+    this.from = Preconditions.<CallHierarchyItem>checkNotNull(from, "from");
+    this.fromRanges = Preconditions.<List<Range>>checkNotNull(fromRanges, "fromRanges");
+  }
+  
+  /**
+   * The item that makes the call.
+   */
+  @Pure
+  @NonNull
+  public CallHierarchyItem getFrom() {
+    return this.from;
+  }
+  
+  /**
+   * The item that makes the call.
+   */
+  public void setFrom(@NonNull final CallHierarchyItem from) {
+    this.from = Preconditions.checkNotNull(from, "from");
+  }
+  
+  /**
+   * The range at which at which the calls appears. This is relative to the caller
+   * denoted by {@link #from}.
+   */
+  @Pure
+  @NonNull
+  public List<Range> getFromRanges() {
+    return this.fromRanges;
+  }
+  
+  /**
+   * The range at which at which the calls appears. This is relative to the caller
+   * denoted by {@link #from}.
+   */
+  public void setFromRanges(@NonNull final List<Range> fromRanges) {
+    this.fromRanges = Preconditions.checkNotNull(fromRanges, "fromRanges");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("from", this.from);
+    b.add("fromRanges", this.fromRanges);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CallHierarchyIncomingCall other = (CallHierarchyIncomingCall) obj;
+    if (this.from == null) {
+      if (other.from != null)
+        return false;
+    } else if (!this.from.equals(other.from))
+      return false;
+    if (this.fromRanges == null) {
+      if (other.fromRanges != null)
+        return false;
+    } else if (!this.fromRanges.equals(other.fromRanges))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.from== null) ? 0 : this.from.hashCode());
+    return prime * result + ((this.fromRanges== null) ? 0 : this.fromRanges.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CallHierarchyIncomingCallsParams.java b/java/org/eclipse/lsp4j/CallHierarchyIncomingCallsParams.java
new file mode 100644
index 0000000..316831b
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CallHierarchyIncomingCallsParams.java
@@ -0,0 +1,83 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.CallHierarchyItem;
+import org.eclipse.lsp4j.WorkDoneProgressAndPartialResultParams;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The parameter of a `callHierarchy/incomingCalls` request.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class CallHierarchyIncomingCallsParams extends WorkDoneProgressAndPartialResultParams {
+  @NonNull
+  private CallHierarchyItem item;
+  
+  public CallHierarchyIncomingCallsParams() {
+  }
+  
+  public CallHierarchyIncomingCallsParams(@NonNull final CallHierarchyItem item) {
+    this.item = Preconditions.<CallHierarchyItem>checkNotNull(item, "item");
+  }
+  
+  @Pure
+  @NonNull
+  public CallHierarchyItem getItem() {
+    return this.item;
+  }
+  
+  public void setItem(@NonNull final CallHierarchyItem item) {
+    this.item = Preconditions.checkNotNull(item, "item");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("item", this.item);
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("partialResultToken", getPartialResultToken());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    CallHierarchyIncomingCallsParams other = (CallHierarchyIncomingCallsParams) obj;
+    if (this.item == null) {
+      if (other.item != null)
+        return false;
+    } else if (!this.item.equals(other.item))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.item== null) ? 0 : this.item.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CallHierarchyItem.java b/java/org/eclipse/lsp4j/CallHierarchyItem.java
new file mode 100644
index 0000000..87108fd
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CallHierarchyItem.java
@@ -0,0 +1,297 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import com.google.gson.annotations.JsonAdapter;
+import java.util.List;
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.SymbolKind;
+import org.eclipse.lsp4j.SymbolTag;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The result of a {@code textDocument/prepareCallHierarchy} request.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class CallHierarchyItem {
+  /**
+   * The name of the item targeted by the call hierarchy request.
+   */
+  @NonNull
+  private String name;
+  
+  /**
+   * More detail for this item, e.g the signature of a function.
+   */
+  private String detail;
+  
+  /**
+   * The kind of this item.
+   */
+  @NonNull
+  private SymbolKind kind;
+  
+  /**
+   * Tags for this item.
+   */
+  private List<SymbolTag> tags;
+  
+  /**
+   * The resource identifier of this item.
+   */
+  @NonNull
+  private String uri;
+  
+  /**
+   * The range enclosing this symbol not including leading/trailing whitespace but everything else
+   * like comments. This information is typically used to determine if the the clients cursor is
+   * inside the symbol to reveal in the symbol in the UI.
+   */
+  @NonNull
+  private Range range;
+  
+  /**
+   * The range that should be selected and revealed when this symbol is being picked, e.g the name of a function.
+   * Must be contained by the the {@link CallHierarchyItem#getRange range}.
+   */
+  @NonNull
+  private Range selectionRange;
+  
+  /**
+   * A data entry field that is preserved between a call hierarchy prepare and
+   * incoming calls or outgoing calls requests.
+   */
+  @JsonAdapter(JsonElementTypeAdapter.Factory.class)
+  private Object data;
+  
+  /**
+   * The name of the item targeted by the call hierarchy request.
+   */
+  @Pure
+  @NonNull
+  public String getName() {
+    return this.name;
+  }
+  
+  /**
+   * The name of the item targeted by the call hierarchy request.
+   */
+  public void setName(@NonNull final String name) {
+    this.name = Preconditions.checkNotNull(name, "name");
+  }
+  
+  /**
+   * More detail for this item, e.g the signature of a function.
+   */
+  @Pure
+  public String getDetail() {
+    return this.detail;
+  }
+  
+  /**
+   * More detail for this item, e.g the signature of a function.
+   */
+  public void setDetail(final String detail) {
+    this.detail = detail;
+  }
+  
+  /**
+   * The kind of this item.
+   */
+  @Pure
+  @NonNull
+  public SymbolKind getKind() {
+    return this.kind;
+  }
+  
+  /**
+   * The kind of this item.
+   */
+  public void setKind(@NonNull final SymbolKind kind) {
+    this.kind = Preconditions.checkNotNull(kind, "kind");
+  }
+  
+  /**
+   * Tags for this item.
+   */
+  @Pure
+  public List<SymbolTag> getTags() {
+    return this.tags;
+  }
+  
+  /**
+   * Tags for this item.
+   */
+  public void setTags(final List<SymbolTag> tags) {
+    this.tags = tags;
+  }
+  
+  /**
+   * The resource identifier of this item.
+   */
+  @Pure
+  @NonNull
+  public String getUri() {
+    return this.uri;
+  }
+  
+  /**
+   * The resource identifier of this item.
+   */
+  public void setUri(@NonNull final String uri) {
+    this.uri = Preconditions.checkNotNull(uri, "uri");
+  }
+  
+  /**
+   * The range enclosing this symbol not including leading/trailing whitespace but everything else
+   * like comments. This information is typically used to determine if the the clients cursor is
+   * inside the symbol to reveal in the symbol in the UI.
+   */
+  @Pure
+  @NonNull
+  public Range getRange() {
+    return this.range;
+  }
+  
+  /**
+   * The range enclosing this symbol not including leading/trailing whitespace but everything else
+   * like comments. This information is typically used to determine if the the clients cursor is
+   * inside the symbol to reveal in the symbol in the UI.
+   */
+  public void setRange(@NonNull final Range range) {
+    this.range = Preconditions.checkNotNull(range, "range");
+  }
+  
+  /**
+   * The range that should be selected and revealed when this symbol is being picked, e.g the name of a function.
+   * Must be contained by the the {@link CallHierarchyItem#getRange range}.
+   */
+  @Pure
+  @NonNull
+  public Range getSelectionRange() {
+    return this.selectionRange;
+  }
+  
+  /**
+   * The range that should be selected and revealed when this symbol is being picked, e.g the name of a function.
+   * Must be contained by the the {@link CallHierarchyItem#getRange range}.
+   */
+  public void setSelectionRange(@NonNull final Range selectionRange) {
+    this.selectionRange = Preconditions.checkNotNull(selectionRange, "selectionRange");
+  }
+  
+  /**
+   * A data entry field that is preserved between a call hierarchy prepare and
+   * incoming calls or outgoing calls requests.
+   */
+  @Pure
+  public Object getData() {
+    return this.data;
+  }
+  
+  /**
+   * A data entry field that is preserved between a call hierarchy prepare and
+   * incoming calls or outgoing calls requests.
+   */
+  public void setData(final Object data) {
+    this.data = data;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("name", this.name);
+    b.add("detail", this.detail);
+    b.add("kind", this.kind);
+    b.add("tags", this.tags);
+    b.add("uri", this.uri);
+    b.add("range", this.range);
+    b.add("selectionRange", this.selectionRange);
+    b.add("data", this.data);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CallHierarchyItem other = (CallHierarchyItem) obj;
+    if (this.name == null) {
+      if (other.name != null)
+        return false;
+    } else if (!this.name.equals(other.name))
+      return false;
+    if (this.detail == null) {
+      if (other.detail != null)
+        return false;
+    } else if (!this.detail.equals(other.detail))
+      return false;
+    if (this.kind == null) {
+      if (other.kind != null)
+        return false;
+    } else if (!this.kind.equals(other.kind))
+      return false;
+    if (this.tags == null) {
+      if (other.tags != null)
+        return false;
+    } else if (!this.tags.equals(other.tags))
+      return false;
+    if (this.uri == null) {
+      if (other.uri != null)
+        return false;
+    } else if (!this.uri.equals(other.uri))
+      return false;
+    if (this.range == null) {
+      if (other.range != null)
+        return false;
+    } else if (!this.range.equals(other.range))
+      return false;
+    if (this.selectionRange == null) {
+      if (other.selectionRange != null)
+        return false;
+    } else if (!this.selectionRange.equals(other.selectionRange))
+      return false;
+    if (this.data == null) {
+      if (other.data != null)
+        return false;
+    } else if (!this.data.equals(other.data))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.name== null) ? 0 : this.name.hashCode());
+    result = prime * result + ((this.detail== null) ? 0 : this.detail.hashCode());
+    result = prime * result + ((this.kind== null) ? 0 : this.kind.hashCode());
+    result = prime * result + ((this.tags== null) ? 0 : this.tags.hashCode());
+    result = prime * result + ((this.uri== null) ? 0 : this.uri.hashCode());
+    result = prime * result + ((this.range== null) ? 0 : this.range.hashCode());
+    result = prime * result + ((this.selectionRange== null) ? 0 : this.selectionRange.hashCode());
+    return prime * result + ((this.data== null) ? 0 : this.data.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CallHierarchyOptions.java b/java/org/eclipse/lsp4j/CallHierarchyOptions.java
new file mode 100644
index 0000000..f081f33
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CallHierarchyOptions.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class CallHierarchyOptions extends AbstractWorkDoneProgressOptions {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CallHierarchyOutgoingCall.java b/java/org/eclipse/lsp4j/CallHierarchyOutgoingCall.java
new file mode 100644
index 0000000..f506a70
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CallHierarchyOutgoingCall.java
@@ -0,0 +1,121 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.CallHierarchyItem;
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Represents an outgoing call, e.g. calling a getter from a method or a method from a constructor etc.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class CallHierarchyOutgoingCall {
+  /**
+   * The item that is called.
+   */
+  @NonNull
+  private CallHierarchyItem to;
+  
+  /**
+   * The range at which this item is called. This is the range relative to the caller, i.e. the {@link CallHierarchyOutgoingCallsParams#item}.
+   */
+  @NonNull
+  private List<Range> fromRanges;
+  
+  public CallHierarchyOutgoingCall() {
+  }
+  
+  public CallHierarchyOutgoingCall(@NonNull final CallHierarchyItem to, @NonNull final List<Range> fromRanges) {
+    this.to = Preconditions.<CallHierarchyItem>checkNotNull(to, "to");
+    this.fromRanges = Preconditions.<List<Range>>checkNotNull(fromRanges, "fromRanges");
+  }
+  
+  /**
+   * The item that is called.
+   */
+  @Pure
+  @NonNull
+  public CallHierarchyItem getTo() {
+    return this.to;
+  }
+  
+  /**
+   * The item that is called.
+   */
+  public void setTo(@NonNull final CallHierarchyItem to) {
+    this.to = Preconditions.checkNotNull(to, "to");
+  }
+  
+  /**
+   * The range at which this item is called. This is the range relative to the caller, i.e. the {@link CallHierarchyOutgoingCallsParams#item}.
+   */
+  @Pure
+  @NonNull
+  public List<Range> getFromRanges() {
+    return this.fromRanges;
+  }
+  
+  /**
+   * The range at which this item is called. This is the range relative to the caller, i.e. the {@link CallHierarchyOutgoingCallsParams#item}.
+   */
+  public void setFromRanges(@NonNull final List<Range> fromRanges) {
+    this.fromRanges = Preconditions.checkNotNull(fromRanges, "fromRanges");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("to", this.to);
+    b.add("fromRanges", this.fromRanges);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CallHierarchyOutgoingCall other = (CallHierarchyOutgoingCall) obj;
+    if (this.to == null) {
+      if (other.to != null)
+        return false;
+    } else if (!this.to.equals(other.to))
+      return false;
+    if (this.fromRanges == null) {
+      if (other.fromRanges != null)
+        return false;
+    } else if (!this.fromRanges.equals(other.fromRanges))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.to== null) ? 0 : this.to.hashCode());
+    return prime * result + ((this.fromRanges== null) ? 0 : this.fromRanges.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CallHierarchyOutgoingCallsParams.java b/java/org/eclipse/lsp4j/CallHierarchyOutgoingCallsParams.java
new file mode 100644
index 0000000..32a4af7
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CallHierarchyOutgoingCallsParams.java
@@ -0,0 +1,83 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.CallHierarchyItem;
+import org.eclipse.lsp4j.WorkDoneProgressAndPartialResultParams;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The parameter of a `callHierarchy/outgoingCalls` request.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class CallHierarchyOutgoingCallsParams extends WorkDoneProgressAndPartialResultParams {
+  @NonNull
+  private CallHierarchyItem item;
+  
+  public CallHierarchyOutgoingCallsParams() {
+  }
+  
+  public CallHierarchyOutgoingCallsParams(@NonNull final CallHierarchyItem item) {
+    this.item = Preconditions.<CallHierarchyItem>checkNotNull(item, "item");
+  }
+  
+  @Pure
+  @NonNull
+  public CallHierarchyItem getItem() {
+    return this.item;
+  }
+  
+  public void setItem(@NonNull final CallHierarchyItem item) {
+    this.item = Preconditions.checkNotNull(item, "item");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("item", this.item);
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("partialResultToken", getPartialResultToken());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    CallHierarchyOutgoingCallsParams other = (CallHierarchyOutgoingCallsParams) obj;
+    if (this.item == null) {
+      if (other.item != null)
+        return false;
+    } else if (!this.item.equals(other.item))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.item== null) ? 0 : this.item.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CallHierarchyPrepareParams.java b/java/org/eclipse/lsp4j/CallHierarchyPrepareParams.java
new file mode 100644
index 0000000..a5570ae
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CallHierarchyPrepareParams.java
@@ -0,0 +1,55 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.TextDocumentPositionAndWorkDoneProgressParams;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The parameter of a `textDocument/prepareCallHierarchy` request.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class CallHierarchyPrepareParams extends TextDocumentPositionAndWorkDoneProgressParams {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("textDocument", getTextDocument());
+    b.add("uri", getUri());
+    b.add("position", getPosition());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CallHierarchyRegistrationOptions.java b/java/org/eclipse/lsp4j/CallHierarchyRegistrationOptions.java
new file mode 100644
index 0000000..006963b
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CallHierarchyRegistrationOptions.java
@@ -0,0 +1,88 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractTextDocumentRegistrationAndWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class CallHierarchyRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  private String id;
+  
+  public CallHierarchyRegistrationOptions() {
+  }
+  
+  public CallHierarchyRegistrationOptions(final String id) {
+    this.id = id;
+  }
+  
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  @Pure
+  public String getId() {
+    return this.id;
+  }
+  
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  public void setId(final String id) {
+    this.id = id;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("id", this.id);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    CallHierarchyRegistrationOptions other = (CallHierarchyRegistrationOptions) obj;
+    if (this.id == null) {
+      if (other.id != null)
+        return false;
+    } else if (!this.id.equals(other.id))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.id== null) ? 0 : this.id.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ChangeAnnotation.java b/java/org/eclipse/lsp4j/ChangeAnnotation.java
new file mode 100644
index 0000000..1d2cf02
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ChangeAnnotation.java
@@ -0,0 +1,151 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Additional information that describes document changes.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class ChangeAnnotation {
+  /**
+   * A human-readable string describing the actual change. The string
+   * is rendered prominent in the user interface.
+   */
+  @NonNull
+  private String label;
+  
+  /**
+   * A flag which indicates that user confirmation is needed
+   * before applying the change.
+   */
+  private Boolean needsConfirmation;
+  
+  /**
+   * A human-readable string which is rendered less prominent in
+   * the user interface.
+   */
+  private String description;
+  
+  public ChangeAnnotation() {
+  }
+  
+  public ChangeAnnotation(@NonNull final String label) {
+    this.label = Preconditions.<String>checkNotNull(label, "label");
+  }
+  
+  /**
+   * A human-readable string describing the actual change. The string
+   * is rendered prominent in the user interface.
+   */
+  @Pure
+  @NonNull
+  public String getLabel() {
+    return this.label;
+  }
+  
+  /**
+   * A human-readable string describing the actual change. The string
+   * is rendered prominent in the user interface.
+   */
+  public void setLabel(@NonNull final String label) {
+    this.label = Preconditions.checkNotNull(label, "label");
+  }
+  
+  /**
+   * A flag which indicates that user confirmation is needed
+   * before applying the change.
+   */
+  @Pure
+  public Boolean getNeedsConfirmation() {
+    return this.needsConfirmation;
+  }
+  
+  /**
+   * A flag which indicates that user confirmation is needed
+   * before applying the change.
+   */
+  public void setNeedsConfirmation(final Boolean needsConfirmation) {
+    this.needsConfirmation = needsConfirmation;
+  }
+  
+  /**
+   * A human-readable string which is rendered less prominent in
+   * the user interface.
+   */
+  @Pure
+  public String getDescription() {
+    return this.description;
+  }
+  
+  /**
+   * A human-readable string which is rendered less prominent in
+   * the user interface.
+   */
+  public void setDescription(final String description) {
+    this.description = description;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("label", this.label);
+    b.add("needsConfirmation", this.needsConfirmation);
+    b.add("description", this.description);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ChangeAnnotation other = (ChangeAnnotation) obj;
+    if (this.label == null) {
+      if (other.label != null)
+        return false;
+    } else if (!this.label.equals(other.label))
+      return false;
+    if (this.needsConfirmation == null) {
+      if (other.needsConfirmation != null)
+        return false;
+    } else if (!this.needsConfirmation.equals(other.needsConfirmation))
+      return false;
+    if (this.description == null) {
+      if (other.description != null)
+        return false;
+    } else if (!this.description.equals(other.description))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.label== null) ? 0 : this.label.hashCode());
+    result = prime * result + ((this.needsConfirmation== null) ? 0 : this.needsConfirmation.hashCode());
+    return prime * result + ((this.description== null) ? 0 : this.description.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ClientCapabilities.java b/java/org/eclipse/lsp4j/ClientCapabilities.java
new file mode 100644
index 0000000..2089726
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ClientCapabilities.java
@@ -0,0 +1,222 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import com.google.gson.annotations.JsonAdapter;
+import org.eclipse.lsp4j.GeneralClientCapabilities;
+import org.eclipse.lsp4j.TextDocumentClientCapabilities;
+import org.eclipse.lsp4j.WindowClientCapabilities;
+import org.eclipse.lsp4j.WorkspaceClientCapabilities;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * `ClientCapabilities` now define capabilities for dynamic registration, workspace and text document features the client supports.
+ * The {@link #experimental} can be used to pass experimental capabilities under development.
+ * For future compatibility a `ClientCapabilities` object literal can have more properties set than currently defined.
+ * Servers receiving a `ClientCapabilities` object literal with unknown properties should ignore these properties.
+ * A missing property should be interpreted as an absence of the capability.
+ * If a property is missing that defines sub properties all sub properties should be interpreted as an absence of the capability.
+ * <p>
+ * Client capabilities got introduced with the version 3.0 of the protocol. They therefore only describe capabilities that got introduced in 3.x or later.
+ * Capabilities that existed in the 2.x version of the protocol are still mandatory for clients. Clients cannot opt out of providing them.
+ * So even if a client omits the {@link TextDocumentClientCapabilities#synchronization}
+ * it is still required that the client provides text document synchronization (e.g. open, changed and close notifications).
+ */
+@SuppressWarnings("all")
+public class ClientCapabilities {
+  /**
+   * Workspace specific client capabilities.
+   */
+  private WorkspaceClientCapabilities workspace;
+  
+  /**
+   * Text document specific client capabilities.
+   */
+  private TextDocumentClientCapabilities textDocument;
+  
+  /**
+   * Window specific client capabilities.
+   */
+  private WindowClientCapabilities window;
+  
+  /**
+   * General client capabilities.
+   * <p>
+   * Since 3.16.0
+   */
+  private GeneralClientCapabilities general;
+  
+  /**
+   * Experimental client capabilities.
+   */
+  @JsonAdapter(JsonElementTypeAdapter.Factory.class)
+  private Object experimental;
+  
+  public ClientCapabilities() {
+  }
+  
+  public ClientCapabilities(final WorkspaceClientCapabilities workspace, final TextDocumentClientCapabilities textDocument, final Object experimental) {
+    this.workspace = workspace;
+    this.textDocument = textDocument;
+    this.experimental = experimental;
+  }
+  
+  public ClientCapabilities(final WorkspaceClientCapabilities workspace, final TextDocumentClientCapabilities textDocument, final WindowClientCapabilities window, final Object experimental) {
+    this.workspace = workspace;
+    this.textDocument = textDocument;
+    this.window = window;
+    this.experimental = experimental;
+  }
+  
+  /**
+   * Workspace specific client capabilities.
+   */
+  @Pure
+  public WorkspaceClientCapabilities getWorkspace() {
+    return this.workspace;
+  }
+  
+  /**
+   * Workspace specific client capabilities.
+   */
+  public void setWorkspace(final WorkspaceClientCapabilities workspace) {
+    this.workspace = workspace;
+  }
+  
+  /**
+   * Text document specific client capabilities.
+   */
+  @Pure
+  public TextDocumentClientCapabilities getTextDocument() {
+    return this.textDocument;
+  }
+  
+  /**
+   * Text document specific client capabilities.
+   */
+  public void setTextDocument(final TextDocumentClientCapabilities textDocument) {
+    this.textDocument = textDocument;
+  }
+  
+  /**
+   * Window specific client capabilities.
+   */
+  @Pure
+  public WindowClientCapabilities getWindow() {
+    return this.window;
+  }
+  
+  /**
+   * Window specific client capabilities.
+   */
+  public void setWindow(final WindowClientCapabilities window) {
+    this.window = window;
+  }
+  
+  /**
+   * General client capabilities.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public GeneralClientCapabilities getGeneral() {
+    return this.general;
+  }
+  
+  /**
+   * General client capabilities.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setGeneral(final GeneralClientCapabilities general) {
+    this.general = general;
+  }
+  
+  /**
+   * Experimental client capabilities.
+   */
+  @Pure
+  public Object getExperimental() {
+    return this.experimental;
+  }
+  
+  /**
+   * Experimental client capabilities.
+   */
+  public void setExperimental(final Object experimental) {
+    this.experimental = experimental;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workspace", this.workspace);
+    b.add("textDocument", this.textDocument);
+    b.add("window", this.window);
+    b.add("general", this.general);
+    b.add("experimental", this.experimental);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ClientCapabilities other = (ClientCapabilities) obj;
+    if (this.workspace == null) {
+      if (other.workspace != null)
+        return false;
+    } else if (!this.workspace.equals(other.workspace))
+      return false;
+    if (this.textDocument == null) {
+      if (other.textDocument != null)
+        return false;
+    } else if (!this.textDocument.equals(other.textDocument))
+      return false;
+    if (this.window == null) {
+      if (other.window != null)
+        return false;
+    } else if (!this.window.equals(other.window))
+      return false;
+    if (this.general == null) {
+      if (other.general != null)
+        return false;
+    } else if (!this.general.equals(other.general))
+      return false;
+    if (this.experimental == null) {
+      if (other.experimental != null)
+        return false;
+    } else if (!this.experimental.equals(other.experimental))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.workspace== null) ? 0 : this.workspace.hashCode());
+    result = prime * result + ((this.textDocument== null) ? 0 : this.textDocument.hashCode());
+    result = prime * result + ((this.window== null) ? 0 : this.window.hashCode());
+    result = prime * result + ((this.general== null) ? 0 : this.general.hashCode());
+    return prime * result + ((this.experimental== null) ? 0 : this.experimental.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ClientInfo.java b/java/org/eclipse/lsp4j/ClientInfo.java
new file mode 100644
index 0000000..5611ae6
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ClientInfo.java
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Information about the client
+ * <p>
+ * Since 3.15.0
+ */
+@SuppressWarnings("all")
+public class ClientInfo {
+  /**
+   * The name of the client as defined by the client.
+   */
+  @NonNull
+  private String name;
+  
+  /**
+   * The client's version as defined by the client.
+   */
+  private String version;
+  
+  public ClientInfo() {
+  }
+  
+  public ClientInfo(@NonNull final String name) {
+    this.name = Preconditions.<String>checkNotNull(name, "name");
+  }
+  
+  public ClientInfo(@NonNull final String name, final String version) {
+    this(name);
+    this.version = version;
+  }
+  
+  /**
+   * The name of the client as defined by the client.
+   */
+  @Pure
+  @NonNull
+  public String getName() {
+    return this.name;
+  }
+  
+  /**
+   * The name of the client as defined by the client.
+   */
+  public void setName(@NonNull final String name) {
+    this.name = Preconditions.checkNotNull(name, "name");
+  }
+  
+  /**
+   * The client's version as defined by the client.
+   */
+  @Pure
+  public String getVersion() {
+    return this.version;
+  }
+  
+  /**
+   * The client's version as defined by the client.
+   */
+  public void setVersion(final String version) {
+    this.version = version;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("name", this.name);
+    b.add("version", this.version);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ClientInfo other = (ClientInfo) obj;
+    if (this.name == null) {
+      if (other.name != null)
+        return false;
+    } else if (!this.name.equals(other.name))
+      return false;
+    if (this.version == null) {
+      if (other.version != null)
+        return false;
+    } else if (!this.version.equals(other.version))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.name== null) ? 0 : this.name.hashCode());
+    return prime * result + ((this.version== null) ? 0 : this.version.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CodeAction.java b/java/org/eclipse/lsp4j/CodeAction.java
new file mode 100644
index 0000000..67b94c1
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CodeAction.java
@@ -0,0 +1,362 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import com.google.gson.annotations.JsonAdapter;
+import java.util.List;
+import org.eclipse.lsp4j.CodeActionDisabled;
+import org.eclipse.lsp4j.Command;
+import org.eclipse.lsp4j.Diagnostic;
+import org.eclipse.lsp4j.WorkspaceEdit;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A code action represents a change that can be performed in code, e.g. to fix a problem or
+ * to refactor code.
+ * <p>
+ * A CodeAction must set either {@link #edit} and/or a {@link #command}.
+ * If both are supplied, the {@link #edit} is applied first, then the {@link #command} is executed.
+ */
+@SuppressWarnings("all")
+public class CodeAction {
+  /**
+   * A short, human-readable, title for this code action.
+   */
+  @NonNull
+  private String title;
+  
+  /**
+   * The kind of the code action.
+   * <p>
+   * Used to filter code actions.
+   */
+  private String kind;
+  
+  /**
+   * The diagnostics that this code action resolves.
+   */
+  private List<Diagnostic> diagnostics;
+  
+  /**
+   * Marks this as a preferred action. Preferred actions are used by the `auto fix` command and can be targeted
+   * by keybindings.
+   * <p>
+   * A quick fix should be marked preferred if it properly addresses the underlying error.
+   * A refactoring should be marked preferred if it is the most reasonable choice of actions to take.
+   * <p>
+   * Since 3.15.0
+   */
+  private Boolean isPreferred;
+  
+  /**
+   * Marks that the code action cannot currently be applied.
+   * <p>
+   * Clients should follow the following guidelines regarding disabled code actions:
+   * <ul>
+   * <li>Disabled code actions are not shown in automatic <a href="https://code.visualstudio.com/docs/editor/editingevolved#_code-action">lightbulb</a>
+   * code action menu.
+   * <li>Disabled actions are shown as faded out in the code action menu when the user request a more specific type
+   * of code action, such as refactorings.
+   * <li>If the user has a <a href="https://code.visualstudio.com/docs/editor/refactoring#_keybindings-for-code-actions">keybinding</a>
+   * that auto applies a code action and only a disabled code actions are returned, the client should show the user an
+   * error message with {@link CodeActionDisabled#reason} in the editor.
+   * </ul><p>
+   * Since 3.16.0
+   */
+  private CodeActionDisabled disabled;
+  
+  /**
+   * The workspace edit this code action performs.
+   */
+  private WorkspaceEdit edit;
+  
+  /**
+   * A command this code action executes. If a code action
+   * provides a edit and a command, first the edit is
+   * executed and then the command.
+   */
+  private Command command;
+  
+  /**
+   * A data entry field that is preserved on a code action between
+   * a `textDocument/codeAction` and a `codeAction/resolve` request.
+   * <p>
+   * Since 3.16.0
+   */
+  @JsonAdapter(JsonElementTypeAdapter.Factory.class)
+  private Object data;
+  
+  public CodeAction() {
+  }
+  
+  public CodeAction(@NonNull final String title) {
+    this.title = Preconditions.<String>checkNotNull(title, "title");
+  }
+  
+  /**
+   * A short, human-readable, title for this code action.
+   */
+  @Pure
+  @NonNull
+  public String getTitle() {
+    return this.title;
+  }
+  
+  /**
+   * A short, human-readable, title for this code action.
+   */
+  public void setTitle(@NonNull final String title) {
+    this.title = Preconditions.checkNotNull(title, "title");
+  }
+  
+  /**
+   * The kind of the code action.
+   * <p>
+   * Used to filter code actions.
+   */
+  @Pure
+  public String getKind() {
+    return this.kind;
+  }
+  
+  /**
+   * The kind of the code action.
+   * <p>
+   * Used to filter code actions.
+   */
+  public void setKind(final String kind) {
+    this.kind = kind;
+  }
+  
+  /**
+   * The diagnostics that this code action resolves.
+   */
+  @Pure
+  public List<Diagnostic> getDiagnostics() {
+    return this.diagnostics;
+  }
+  
+  /**
+   * The diagnostics that this code action resolves.
+   */
+  public void setDiagnostics(final List<Diagnostic> diagnostics) {
+    this.diagnostics = diagnostics;
+  }
+  
+  /**
+   * Marks this as a preferred action. Preferred actions are used by the `auto fix` command and can be targeted
+   * by keybindings.
+   * <p>
+   * A quick fix should be marked preferred if it properly addresses the underlying error.
+   * A refactoring should be marked preferred if it is the most reasonable choice of actions to take.
+   * <p>
+   * Since 3.15.0
+   */
+  @Pure
+  public Boolean getIsPreferred() {
+    return this.isPreferred;
+  }
+  
+  /**
+   * Marks this as a preferred action. Preferred actions are used by the `auto fix` command and can be targeted
+   * by keybindings.
+   * <p>
+   * A quick fix should be marked preferred if it properly addresses the underlying error.
+   * A refactoring should be marked preferred if it is the most reasonable choice of actions to take.
+   * <p>
+   * Since 3.15.0
+   */
+  public void setIsPreferred(final Boolean isPreferred) {
+    this.isPreferred = isPreferred;
+  }
+  
+  /**
+   * Marks that the code action cannot currently be applied.
+   * <p>
+   * Clients should follow the following guidelines regarding disabled code actions:
+   * <ul>
+   * <li>Disabled code actions are not shown in automatic <a href="https://code.visualstudio.com/docs/editor/editingevolved#_code-action">lightbulb</a>
+   * code action menu.
+   * <li>Disabled actions are shown as faded out in the code action menu when the user request a more specific type
+   * of code action, such as refactorings.
+   * <li>If the user has a <a href="https://code.visualstudio.com/docs/editor/refactoring#_keybindings-for-code-actions">keybinding</a>
+   * that auto applies a code action and only a disabled code actions are returned, the client should show the user an
+   * error message with {@link CodeActionDisabled#reason} in the editor.
+   * </ul><p>
+   * Since 3.16.0
+   */
+  @Pure
+  public CodeActionDisabled getDisabled() {
+    return this.disabled;
+  }
+  
+  /**
+   * Marks that the code action cannot currently be applied.
+   * <p>
+   * Clients should follow the following guidelines regarding disabled code actions:
+   * <ul>
+   * <li>Disabled code actions are not shown in automatic <a href="https://code.visualstudio.com/docs/editor/editingevolved#_code-action">lightbulb</a>
+   * code action menu.
+   * <li>Disabled actions are shown as faded out in the code action menu when the user request a more specific type
+   * of code action, such as refactorings.
+   * <li>If the user has a <a href="https://code.visualstudio.com/docs/editor/refactoring#_keybindings-for-code-actions">keybinding</a>
+   * that auto applies a code action and only a disabled code actions are returned, the client should show the user an
+   * error message with {@link CodeActionDisabled#reason} in the editor.
+   * </ul><p>
+   * Since 3.16.0
+   */
+  public void setDisabled(final CodeActionDisabled disabled) {
+    this.disabled = disabled;
+  }
+  
+  /**
+   * The workspace edit this code action performs.
+   */
+  @Pure
+  public WorkspaceEdit getEdit() {
+    return this.edit;
+  }
+  
+  /**
+   * The workspace edit this code action performs.
+   */
+  public void setEdit(final WorkspaceEdit edit) {
+    this.edit = edit;
+  }
+  
+  /**
+   * A command this code action executes. If a code action
+   * provides a edit and a command, first the edit is
+   * executed and then the command.
+   */
+  @Pure
+  public Command getCommand() {
+    return this.command;
+  }
+  
+  /**
+   * A command this code action executes. If a code action
+   * provides a edit and a command, first the edit is
+   * executed and then the command.
+   */
+  public void setCommand(final Command command) {
+    this.command = command;
+  }
+  
+  /**
+   * A data entry field that is preserved on a code action between
+   * a `textDocument/codeAction` and a `codeAction/resolve` request.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public Object getData() {
+    return this.data;
+  }
+  
+  /**
+   * A data entry field that is preserved on a code action between
+   * a `textDocument/codeAction` and a `codeAction/resolve` request.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setData(final Object data) {
+    this.data = data;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("title", this.title);
+    b.add("kind", this.kind);
+    b.add("diagnostics", this.diagnostics);
+    b.add("isPreferred", this.isPreferred);
+    b.add("disabled", this.disabled);
+    b.add("edit", this.edit);
+    b.add("command", this.command);
+    b.add("data", this.data);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CodeAction other = (CodeAction) obj;
+    if (this.title == null) {
+      if (other.title != null)
+        return false;
+    } else if (!this.title.equals(other.title))
+      return false;
+    if (this.kind == null) {
+      if (other.kind != null)
+        return false;
+    } else if (!this.kind.equals(other.kind))
+      return false;
+    if (this.diagnostics == null) {
+      if (other.diagnostics != null)
+        return false;
+    } else if (!this.diagnostics.equals(other.diagnostics))
+      return false;
+    if (this.isPreferred == null) {
+      if (other.isPreferred != null)
+        return false;
+    } else if (!this.isPreferred.equals(other.isPreferred))
+      return false;
+    if (this.disabled == null) {
+      if (other.disabled != null)
+        return false;
+    } else if (!this.disabled.equals(other.disabled))
+      return false;
+    if (this.edit == null) {
+      if (other.edit != null)
+        return false;
+    } else if (!this.edit.equals(other.edit))
+      return false;
+    if (this.command == null) {
+      if (other.command != null)
+        return false;
+    } else if (!this.command.equals(other.command))
+      return false;
+    if (this.data == null) {
+      if (other.data != null)
+        return false;
+    } else if (!this.data.equals(other.data))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.title== null) ? 0 : this.title.hashCode());
+    result = prime * result + ((this.kind== null) ? 0 : this.kind.hashCode());
+    result = prime * result + ((this.diagnostics== null) ? 0 : this.diagnostics.hashCode());
+    result = prime * result + ((this.isPreferred== null) ? 0 : this.isPreferred.hashCode());
+    result = prime * result + ((this.disabled== null) ? 0 : this.disabled.hashCode());
+    result = prime * result + ((this.edit== null) ? 0 : this.edit.hashCode());
+    result = prime * result + ((this.command== null) ? 0 : this.command.hashCode());
+    return prime * result + ((this.data== null) ? 0 : this.data.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CodeActionCapabilities.java b/java/org/eclipse/lsp4j/CodeActionCapabilities.java
new file mode 100644
index 0000000..e0ecbed
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CodeActionCapabilities.java
@@ -0,0 +1,287 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.CodeActionLiteralSupportCapabilities;
+import org.eclipse.lsp4j.CodeActionResolveSupportCapabilities;
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the `textDocument/codeAction`
+ */
+@SuppressWarnings("all")
+public class CodeActionCapabilities extends DynamicRegistrationCapabilities {
+  /**
+   * The client support code action literals as a valid
+   * response of the `textDocument/codeAction` request.
+   */
+  private CodeActionLiteralSupportCapabilities codeActionLiteralSupport;
+  
+  /**
+   * Whether code action supports the {@link CodeAction#isPreferred} property.
+   * <p>
+   * Since 3.15.0
+   */
+  private Boolean isPreferredSupport;
+  
+  /**
+   * Whether code action supports the {@link CodeAction#disabled} property.
+   * <p>
+   * Since 3.16.0
+   */
+  private Boolean disabledSupport;
+  
+  /**
+   * Whether code action supports the {@link CodeAction#data} property which is
+   * preserved between a `textDocument/codeAction` and a
+   * `codeAction/resolve` request.
+   * <p>
+   * Since 3.16.0
+   */
+  private Boolean dataSupport;
+  
+  /**
+   * Whether the client supports resolving additional code action
+   * properties via a separate `codeAction/resolve` request.
+   * <p>
+   * Since 3.16.0
+   */
+  private CodeActionResolveSupportCapabilities resolveSupport;
+  
+  /**
+   * Whether the client honors the change annotations in
+   * text edits and resource operations returned via the
+   * {@link CodeAction#edit} property by for example presenting
+   * the workspace edit in the user interface and asking
+   * for confirmation.
+   * <p>
+   * Since 3.16.0
+   */
+  private Boolean honorsChangeAnnotations;
+  
+  public CodeActionCapabilities() {
+  }
+  
+  public CodeActionCapabilities(final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+  }
+  
+  public CodeActionCapabilities(final CodeActionLiteralSupportCapabilities codeActionLiteralSupport, final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+    this.codeActionLiteralSupport = codeActionLiteralSupport;
+  }
+  
+  public CodeActionCapabilities(final CodeActionLiteralSupportCapabilities codeActionLiteralSupport, final Boolean dynamicRegistration, final Boolean isPreferredSupport) {
+    this(codeActionLiteralSupport, dynamicRegistration);
+    this.isPreferredSupport = isPreferredSupport;
+  }
+  
+  /**
+   * The client support code action literals as a valid
+   * response of the `textDocument/codeAction` request.
+   */
+  @Pure
+  public CodeActionLiteralSupportCapabilities getCodeActionLiteralSupport() {
+    return this.codeActionLiteralSupport;
+  }
+  
+  /**
+   * The client support code action literals as a valid
+   * response of the `textDocument/codeAction` request.
+   */
+  public void setCodeActionLiteralSupport(final CodeActionLiteralSupportCapabilities codeActionLiteralSupport) {
+    this.codeActionLiteralSupport = codeActionLiteralSupport;
+  }
+  
+  /**
+   * Whether code action supports the {@link CodeAction#isPreferred} property.
+   * <p>
+   * Since 3.15.0
+   */
+  @Pure
+  public Boolean getIsPreferredSupport() {
+    return this.isPreferredSupport;
+  }
+  
+  /**
+   * Whether code action supports the {@link CodeAction#isPreferred} property.
+   * <p>
+   * Since 3.15.0
+   */
+  public void setIsPreferredSupport(final Boolean isPreferredSupport) {
+    this.isPreferredSupport = isPreferredSupport;
+  }
+  
+  /**
+   * Whether code action supports the {@link CodeAction#disabled} property.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public Boolean getDisabledSupport() {
+    return this.disabledSupport;
+  }
+  
+  /**
+   * Whether code action supports the {@link CodeAction#disabled} property.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setDisabledSupport(final Boolean disabledSupport) {
+    this.disabledSupport = disabledSupport;
+  }
+  
+  /**
+   * Whether code action supports the {@link CodeAction#data} property which is
+   * preserved between a `textDocument/codeAction` and a
+   * `codeAction/resolve` request.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public Boolean getDataSupport() {
+    return this.dataSupport;
+  }
+  
+  /**
+   * Whether code action supports the {@link CodeAction#data} property which is
+   * preserved between a `textDocument/codeAction` and a
+   * `codeAction/resolve` request.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setDataSupport(final Boolean dataSupport) {
+    this.dataSupport = dataSupport;
+  }
+  
+  /**
+   * Whether the client supports resolving additional code action
+   * properties via a separate `codeAction/resolve` request.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public CodeActionResolveSupportCapabilities getResolveSupport() {
+    return this.resolveSupport;
+  }
+  
+  /**
+   * Whether the client supports resolving additional code action
+   * properties via a separate `codeAction/resolve` request.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setResolveSupport(final CodeActionResolveSupportCapabilities resolveSupport) {
+    this.resolveSupport = resolveSupport;
+  }
+  
+  /**
+   * Whether the client honors the change annotations in
+   * text edits and resource operations returned via the
+   * {@link CodeAction#edit} property by for example presenting
+   * the workspace edit in the user interface and asking
+   * for confirmation.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public Boolean getHonorsChangeAnnotations() {
+    return this.honorsChangeAnnotations;
+  }
+  
+  /**
+   * Whether the client honors the change annotations in
+   * text edits and resource operations returned via the
+   * {@link CodeAction#edit} property by for example presenting
+   * the workspace edit in the user interface and asking
+   * for confirmation.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setHonorsChangeAnnotations(final Boolean honorsChangeAnnotations) {
+    this.honorsChangeAnnotations = honorsChangeAnnotations;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("codeActionLiteralSupport", this.codeActionLiteralSupport);
+    b.add("isPreferredSupport", this.isPreferredSupport);
+    b.add("disabledSupport", this.disabledSupport);
+    b.add("dataSupport", this.dataSupport);
+    b.add("resolveSupport", this.resolveSupport);
+    b.add("honorsChangeAnnotations", this.honorsChangeAnnotations);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    CodeActionCapabilities other = (CodeActionCapabilities) obj;
+    if (this.codeActionLiteralSupport == null) {
+      if (other.codeActionLiteralSupport != null)
+        return false;
+    } else if (!this.codeActionLiteralSupport.equals(other.codeActionLiteralSupport))
+      return false;
+    if (this.isPreferredSupport == null) {
+      if (other.isPreferredSupport != null)
+        return false;
+    } else if (!this.isPreferredSupport.equals(other.isPreferredSupport))
+      return false;
+    if (this.disabledSupport == null) {
+      if (other.disabledSupport != null)
+        return false;
+    } else if (!this.disabledSupport.equals(other.disabledSupport))
+      return false;
+    if (this.dataSupport == null) {
+      if (other.dataSupport != null)
+        return false;
+    } else if (!this.dataSupport.equals(other.dataSupport))
+      return false;
+    if (this.resolveSupport == null) {
+      if (other.resolveSupport != null)
+        return false;
+    } else if (!this.resolveSupport.equals(other.resolveSupport))
+      return false;
+    if (this.honorsChangeAnnotations == null) {
+      if (other.honorsChangeAnnotations != null)
+        return false;
+    } else if (!this.honorsChangeAnnotations.equals(other.honorsChangeAnnotations))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.codeActionLiteralSupport== null) ? 0 : this.codeActionLiteralSupport.hashCode());
+    result = prime * result + ((this.isPreferredSupport== null) ? 0 : this.isPreferredSupport.hashCode());
+    result = prime * result + ((this.disabledSupport== null) ? 0 : this.disabledSupport.hashCode());
+    result = prime * result + ((this.dataSupport== null) ? 0 : this.dataSupport.hashCode());
+    result = prime * result + ((this.resolveSupport== null) ? 0 : this.resolveSupport.hashCode());
+    return prime * result + ((this.honorsChangeAnnotations== null) ? 0 : this.honorsChangeAnnotations.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CodeActionContext.java b/java/org/eclipse/lsp4j/CodeActionContext.java
new file mode 100644
index 0000000..ad4425d
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CodeActionContext.java
@@ -0,0 +1,135 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.Diagnostic;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Contains additional diagnostic information about the context in which a code action is run.
+ */
+@SuppressWarnings("all")
+public class CodeActionContext {
+  /**
+   * An array of diagnostics.
+   */
+  @NonNull
+  private List<Diagnostic> diagnostics;
+  
+  /**
+   * Requested kind of actions to return.
+   * <p>
+   * Actions not of this kind are filtered out by the client before being shown. So servers
+   * can omit computing them.
+   * <p>
+   * See {@link CodeActionKind} for allowed values.
+   */
+  private List<String> only;
+  
+  public CodeActionContext() {
+  }
+  
+  public CodeActionContext(@NonNull final List<Diagnostic> diagnostics) {
+    this.diagnostics = Preconditions.<List<Diagnostic>>checkNotNull(diagnostics, "diagnostics");
+  }
+  
+  public CodeActionContext(@NonNull final List<Diagnostic> diagnostics, final List<String> only) {
+    this(diagnostics);
+    this.only = only;
+  }
+  
+  /**
+   * An array of diagnostics.
+   */
+  @Pure
+  @NonNull
+  public List<Diagnostic> getDiagnostics() {
+    return this.diagnostics;
+  }
+  
+  /**
+   * An array of diagnostics.
+   */
+  public void setDiagnostics(@NonNull final List<Diagnostic> diagnostics) {
+    this.diagnostics = Preconditions.checkNotNull(diagnostics, "diagnostics");
+  }
+  
+  /**
+   * Requested kind of actions to return.
+   * <p>
+   * Actions not of this kind are filtered out by the client before being shown. So servers
+   * can omit computing them.
+   * <p>
+   * See {@link CodeActionKind} for allowed values.
+   */
+  @Pure
+  public List<String> getOnly() {
+    return this.only;
+  }
+  
+  /**
+   * Requested kind of actions to return.
+   * <p>
+   * Actions not of this kind are filtered out by the client before being shown. So servers
+   * can omit computing them.
+   * <p>
+   * See {@link CodeActionKind} for allowed values.
+   */
+  public void setOnly(final List<String> only) {
+    this.only = only;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("diagnostics", this.diagnostics);
+    b.add("only", this.only);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CodeActionContext other = (CodeActionContext) obj;
+    if (this.diagnostics == null) {
+      if (other.diagnostics != null)
+        return false;
+    } else if (!this.diagnostics.equals(other.diagnostics))
+      return false;
+    if (this.only == null) {
+      if (other.only != null)
+        return false;
+    } else if (!this.only.equals(other.only))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.diagnostics== null) ? 0 : this.diagnostics.hashCode());
+    return prime * result + ((this.only== null) ? 0 : this.only.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CodeActionDisabled.java b/java/org/eclipse/lsp4j/CodeActionDisabled.java
new file mode 100644
index 0000000..abbc341
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CodeActionDisabled.java
@@ -0,0 +1,102 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Marks that the code action cannot currently be applied.
+ * <p>
+ * Clients should follow the following guidelines regarding disabled code actions:
+ * <ul>
+ * <li>Disabled code actions are not shown in automatic <a href="https://code.visualstudio.com/docs/editor/editingevolved#_code-action">lightbulb</a>
+ * code action menu.
+ * <li>Disabled actions are shown as faded out in the code action menu when the user request a more specific type
+ * of code action, such as refactorings.
+ * <li>If the user has a <a href="https://code.visualstudio.com/docs/editor/refactoring#_keybindings-for-code-actions">keybinding</a>
+ * that auto applies a code action and only a disabled code actions are returned, the client should show the user an
+ * error message with {@link #reason} in the editor.
+ * </ul><p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class CodeActionDisabled {
+  /**
+   * Human readable description of why the code action is currently disabled.
+   * <p>
+   * This is displayed in the code actions UI.
+   */
+  @NonNull
+  private String reason;
+  
+  public CodeActionDisabled() {
+  }
+  
+  public CodeActionDisabled(@NonNull final String reason) {
+    this.reason = Preconditions.<String>checkNotNull(reason, "reason");
+  }
+  
+  /**
+   * Human readable description of why the code action is currently disabled.
+   * <p>
+   * This is displayed in the code actions UI.
+   */
+  @Pure
+  @NonNull
+  public String getReason() {
+    return this.reason;
+  }
+  
+  /**
+   * Human readable description of why the code action is currently disabled.
+   * <p>
+   * This is displayed in the code actions UI.
+   */
+  public void setReason(@NonNull final String reason) {
+    this.reason = Preconditions.checkNotNull(reason, "reason");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("reason", this.reason);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CodeActionDisabled other = (CodeActionDisabled) obj;
+    if (this.reason == null) {
+      if (other.reason != null)
+        return false;
+    } else if (!this.reason.equals(other.reason))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.reason== null) ? 0 : this.reason.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CodeActionKind.java b/java/org/eclipse/lsp4j/CodeActionKind.java
new file mode 100644
index 0000000..d672fd7
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CodeActionKind.java
@@ -0,0 +1,80 @@
+/******************************************************************************
+ * Copyright (c) 2018 Microsoft Corporation and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j;
+
+/**
+ * The kind of a code action.
+ *
+ * Kinds are a hierarchical list of identifiers separated by `.`, e.g.
+ * `"refactor.extract.function"`.
+ *
+ * The set of kinds is open and client needs to announce the kinds it supports
+ * to the server during initialization.
+ */
+
+public final class CodeActionKind {
+
+	private CodeActionKind() {
+	}
+
+	/**
+	 * Base kind for quickfix actions: 'quickfix'
+	 */
+	public static final String QuickFix = "quickfix";
+
+	/**
+	 * Base kind for refactoring actions: 'refactor'
+	 */
+	public static final String Refactor = "refactor";
+
+	/**
+	 * Base kind for refactoring extraction actions: 'refactor.extract'
+	 *
+	 * Example extract actions:
+	 *
+	 * - Extract method - Extract function - Extract variable - Extract interface
+	 * from class - ...
+	 */
+	public static final String RefactorExtract = "refactor.extract";
+
+	/**
+	 * Base kind for refactoring inline actions: 'refactor.inline'
+	 *
+	 * Example inline actions:
+	 *
+	 * - Inline function - Inline variable - Inline constant - ...
+	 */
+	public static final String RefactorInline = "refactor.inline";
+
+	/**
+	 * Base kind for refactoring rewrite actions: 'refactor.rewrite'
+	 *
+	 * Example rewrite actions:
+	 *
+	 * - Convert JavaScript function to class - Add or remove parameter -
+	 * Encapsulate field - Make method static - Move method to base class - ...
+	 */
+	public static final String RefactorRewrite = "refactor.rewrite";
+
+	/**
+	 * Base kind for source actions: `source`
+	 *
+	 * Source code actions apply to the entire file.
+	 */
+	public static final String Source = "source";
+
+	/**
+	 * Base kind for an organize imports source action: `source.organizeImports`
+	 */
+	public static final String SourceOrganizeImports = "source.organizeImports";
+}
+
diff --git a/java/org/eclipse/lsp4j/CodeActionKindCapabilities.java b/java/org/eclipse/lsp4j/CodeActionKindCapabilities.java
new file mode 100644
index 0000000..27ea9d7
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CodeActionKindCapabilities.java
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class CodeActionKindCapabilities {
+  /**
+   * The code action kind values the client supports. When this
+   * property exists the client also guarantees that it will
+   * handle values outside its set gracefully and falls back
+   * to a default value when unknown.
+   * <p>
+   * See {@link CodeActionKind} for allowed values.
+   */
+  @NonNull
+  private List<String> valueSet;
+  
+  public CodeActionKindCapabilities() {
+    ArrayList<String> _arrayList = new ArrayList<String>();
+    this.valueSet = _arrayList;
+  }
+  
+  public CodeActionKindCapabilities(@NonNull final List<String> valueSet) {
+    this.valueSet = Preconditions.<List<String>>checkNotNull(valueSet, "valueSet");
+  }
+  
+  /**
+   * The code action kind values the client supports. When this
+   * property exists the client also guarantees that it will
+   * handle values outside its set gracefully and falls back
+   * to a default value when unknown.
+   * <p>
+   * See {@link CodeActionKind} for allowed values.
+   */
+  @Pure
+  @NonNull
+  public List<String> getValueSet() {
+    return this.valueSet;
+  }
+  
+  /**
+   * The code action kind values the client supports. When this
+   * property exists the client also guarantees that it will
+   * handle values outside its set gracefully and falls back
+   * to a default value when unknown.
+   * <p>
+   * See {@link CodeActionKind} for allowed values.
+   */
+  public void setValueSet(@NonNull final List<String> valueSet) {
+    this.valueSet = Preconditions.checkNotNull(valueSet, "valueSet");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("valueSet", this.valueSet);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CodeActionKindCapabilities other = (CodeActionKindCapabilities) obj;
+    if (this.valueSet == null) {
+      if (other.valueSet != null)
+        return false;
+    } else if (!this.valueSet.equals(other.valueSet))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.valueSet== null) ? 0 : this.valueSet.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CodeActionLiteralSupportCapabilities.java b/java/org/eclipse/lsp4j/CodeActionLiteralSupportCapabilities.java
new file mode 100644
index 0000000..d75b47d
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CodeActionLiteralSupportCapabilities.java
@@ -0,0 +1,81 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.CodeActionKindCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class CodeActionLiteralSupportCapabilities {
+  /**
+   * The code action kind is support with the following value
+   * set.
+   */
+  private CodeActionKindCapabilities codeActionKind;
+  
+  public CodeActionLiteralSupportCapabilities() {
+  }
+  
+  public CodeActionLiteralSupportCapabilities(final CodeActionKindCapabilities codeActionKind) {
+    this.codeActionKind = codeActionKind;
+  }
+  
+  /**
+   * The code action kind is support with the following value
+   * set.
+   */
+  @Pure
+  public CodeActionKindCapabilities getCodeActionKind() {
+    return this.codeActionKind;
+  }
+  
+  /**
+   * The code action kind is support with the following value
+   * set.
+   */
+  public void setCodeActionKind(final CodeActionKindCapabilities codeActionKind) {
+    this.codeActionKind = codeActionKind;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("codeActionKind", this.codeActionKind);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CodeActionLiteralSupportCapabilities other = (CodeActionLiteralSupportCapabilities) obj;
+    if (this.codeActionKind == null) {
+      if (other.codeActionKind != null)
+        return false;
+    } else if (!this.codeActionKind.equals(other.codeActionKind))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.codeActionKind== null) ? 0 : this.codeActionKind.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CodeActionOptions.java b/java/org/eclipse/lsp4j/CodeActionOptions.java
new file mode 100644
index 0000000..c4ba37f
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CodeActionOptions.java
@@ -0,0 +1,132 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.AbstractWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Code Action options.
+ */
+@SuppressWarnings("all")
+public class CodeActionOptions extends AbstractWorkDoneProgressOptions {
+  /**
+   * CodeActionKinds that this server may return.
+   * <p>
+   * The list of kinds may be generic, such as {@link CodeActionKind#Refactor}, or the server
+   * may list out every specific kind they provide.
+   */
+  private List<String> codeActionKinds;
+  
+  /**
+   * The server provides support to resolve additional
+   * information for a code action.
+   * <p>
+   * Since 3.16.0
+   */
+  private Boolean resolveProvider;
+  
+  public CodeActionOptions() {
+  }
+  
+  public CodeActionOptions(final List<String> codeActionKinds) {
+    this.codeActionKinds = codeActionKinds;
+  }
+  
+  /**
+   * CodeActionKinds that this server may return.
+   * <p>
+   * The list of kinds may be generic, such as {@link CodeActionKind#Refactor}, or the server
+   * may list out every specific kind they provide.
+   */
+  @Pure
+  public List<String> getCodeActionKinds() {
+    return this.codeActionKinds;
+  }
+  
+  /**
+   * CodeActionKinds that this server may return.
+   * <p>
+   * The list of kinds may be generic, such as {@link CodeActionKind#Refactor}, or the server
+   * may list out every specific kind they provide.
+   */
+  public void setCodeActionKinds(final List<String> codeActionKinds) {
+    this.codeActionKinds = codeActionKinds;
+  }
+  
+  /**
+   * The server provides support to resolve additional
+   * information for a code action.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public Boolean getResolveProvider() {
+    return this.resolveProvider;
+  }
+  
+  /**
+   * The server provides support to resolve additional
+   * information for a code action.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setResolveProvider(final Boolean resolveProvider) {
+    this.resolveProvider = resolveProvider;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("codeActionKinds", this.codeActionKinds);
+    b.add("resolveProvider", this.resolveProvider);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    CodeActionOptions other = (CodeActionOptions) obj;
+    if (this.codeActionKinds == null) {
+      if (other.codeActionKinds != null)
+        return false;
+    } else if (!this.codeActionKinds.equals(other.codeActionKinds))
+      return false;
+    if (this.resolveProvider == null) {
+      if (other.resolveProvider != null)
+        return false;
+    } else if (!this.resolveProvider.equals(other.resolveProvider))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.codeActionKinds== null) ? 0 : this.codeActionKinds.hashCode());
+    return prime * result + ((this.resolveProvider== null) ? 0 : this.resolveProvider.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CodeActionParams.java b/java/org/eclipse/lsp4j/CodeActionParams.java
new file mode 100644
index 0000000..5f94688
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CodeActionParams.java
@@ -0,0 +1,155 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.CodeActionContext;
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.WorkDoneProgressAndPartialResultParams;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The code action request is sent from the client to the server to compute commands for a given text document and range.
+ * These commands are typically code fixes to either fix problems or to beautify/refactor code.
+ */
+@SuppressWarnings("all")
+public class CodeActionParams extends WorkDoneProgressAndPartialResultParams {
+  /**
+   * The document in which the command was invoked.
+   */
+  @NonNull
+  private TextDocumentIdentifier textDocument;
+  
+  /**
+   * The range for which the command was invoked.
+   */
+  @NonNull
+  private Range range;
+  
+  /**
+   * Context carrying additional information.
+   */
+  @NonNull
+  private CodeActionContext context;
+  
+  public CodeActionParams() {
+  }
+  
+  public CodeActionParams(@NonNull final TextDocumentIdentifier textDocument, @NonNull final Range range, @NonNull final CodeActionContext context) {
+    this.textDocument = Preconditions.<TextDocumentIdentifier>checkNotNull(textDocument, "textDocument");
+    this.range = Preconditions.<Range>checkNotNull(range, "range");
+    this.context = Preconditions.<CodeActionContext>checkNotNull(context, "context");
+  }
+  
+  /**
+   * The document in which the command was invoked.
+   */
+  @Pure
+  @NonNull
+  public TextDocumentIdentifier getTextDocument() {
+    return this.textDocument;
+  }
+  
+  /**
+   * The document in which the command was invoked.
+   */
+  public void setTextDocument(@NonNull final TextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.checkNotNull(textDocument, "textDocument");
+  }
+  
+  /**
+   * The range for which the command was invoked.
+   */
+  @Pure
+  @NonNull
+  public Range getRange() {
+    return this.range;
+  }
+  
+  /**
+   * The range for which the command was invoked.
+   */
+  public void setRange(@NonNull final Range range) {
+    this.range = Preconditions.checkNotNull(range, "range");
+  }
+  
+  /**
+   * Context carrying additional information.
+   */
+  @Pure
+  @NonNull
+  public CodeActionContext getContext() {
+    return this.context;
+  }
+  
+  /**
+   * Context carrying additional information.
+   */
+  public void setContext(@NonNull final CodeActionContext context) {
+    this.context = Preconditions.checkNotNull(context, "context");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("textDocument", this.textDocument);
+    b.add("range", this.range);
+    b.add("context", this.context);
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("partialResultToken", getPartialResultToken());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    CodeActionParams other = (CodeActionParams) obj;
+    if (this.textDocument == null) {
+      if (other.textDocument != null)
+        return false;
+    } else if (!this.textDocument.equals(other.textDocument))
+      return false;
+    if (this.range == null) {
+      if (other.range != null)
+        return false;
+    } else if (!this.range.equals(other.range))
+      return false;
+    if (this.context == null) {
+      if (other.context != null)
+        return false;
+    } else if (!this.context.equals(other.context))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.textDocument== null) ? 0 : this.textDocument.hashCode());
+    result = prime * result + ((this.range== null) ? 0 : this.range.hashCode());
+    return prime * result + ((this.context== null) ? 0 : this.context.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CodeActionRegistrationOptions.java b/java/org/eclipse/lsp4j/CodeActionRegistrationOptions.java
new file mode 100644
index 0000000..c7c5a95
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CodeActionRegistrationOptions.java
@@ -0,0 +1,133 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.AbstractTextDocumentRegistrationAndWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Code Action registration options.
+ */
+@SuppressWarnings("all")
+public class CodeActionRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+  /**
+   * CodeActionKinds that this server may return.
+   * <p>
+   * The list of kinds may be generic, such as {@link CodeActionKind#Refactor}, or the server
+   * may list out every specific kind they provide.
+   */
+  private List<String> codeActionKinds;
+  
+  /**
+   * The server provides support to resolve additional
+   * information for a code action.
+   * <p>
+   * Since 3.16.0
+   */
+  private Boolean resolveProvider;
+  
+  public CodeActionRegistrationOptions() {
+  }
+  
+  public CodeActionRegistrationOptions(final List<String> codeActionKinds) {
+    this.codeActionKinds = codeActionKinds;
+  }
+  
+  /**
+   * CodeActionKinds that this server may return.
+   * <p>
+   * The list of kinds may be generic, such as {@link CodeActionKind#Refactor}, or the server
+   * may list out every specific kind they provide.
+   */
+  @Pure
+  public List<String> getCodeActionKinds() {
+    return this.codeActionKinds;
+  }
+  
+  /**
+   * CodeActionKinds that this server may return.
+   * <p>
+   * The list of kinds may be generic, such as {@link CodeActionKind#Refactor}, or the server
+   * may list out every specific kind they provide.
+   */
+  public void setCodeActionKinds(final List<String> codeActionKinds) {
+    this.codeActionKinds = codeActionKinds;
+  }
+  
+  /**
+   * The server provides support to resolve additional
+   * information for a code action.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public Boolean getResolveProvider() {
+    return this.resolveProvider;
+  }
+  
+  /**
+   * The server provides support to resolve additional
+   * information for a code action.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setResolveProvider(final Boolean resolveProvider) {
+    this.resolveProvider = resolveProvider;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("codeActionKinds", this.codeActionKinds);
+    b.add("resolveProvider", this.resolveProvider);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    CodeActionRegistrationOptions other = (CodeActionRegistrationOptions) obj;
+    if (this.codeActionKinds == null) {
+      if (other.codeActionKinds != null)
+        return false;
+    } else if (!this.codeActionKinds.equals(other.codeActionKinds))
+      return false;
+    if (this.resolveProvider == null) {
+      if (other.resolveProvider != null)
+        return false;
+    } else if (!this.resolveProvider.equals(other.resolveProvider))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.codeActionKinds== null) ? 0 : this.codeActionKinds.hashCode());
+    return prime * result + ((this.resolveProvider== null) ? 0 : this.resolveProvider.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CodeActionResolveSupportCapabilities.java b/java/org/eclipse/lsp4j/CodeActionResolveSupportCapabilities.java
new file mode 100644
index 0000000..0a57d39
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CodeActionResolveSupportCapabilities.java
@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Whether the client supports resolving additional code action
+ * properties via a separate `codeAction/resolve` request.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class CodeActionResolveSupportCapabilities {
+  /**
+   * The properties that a client can resolve lazily.
+   */
+  @NonNull
+  private List<String> properties;
+  
+  public CodeActionResolveSupportCapabilities() {
+    ArrayList<String> _arrayList = new ArrayList<String>();
+    this.properties = _arrayList;
+  }
+  
+  public CodeActionResolveSupportCapabilities(@NonNull final List<String> properties) {
+    this.properties = Preconditions.<List<String>>checkNotNull(properties, "properties");
+  }
+  
+  /**
+   * The properties that a client can resolve lazily.
+   */
+  @Pure
+  @NonNull
+  public List<String> getProperties() {
+    return this.properties;
+  }
+  
+  /**
+   * The properties that a client can resolve lazily.
+   */
+  public void setProperties(@NonNull final List<String> properties) {
+    this.properties = Preconditions.checkNotNull(properties, "properties");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("properties", this.properties);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CodeActionResolveSupportCapabilities other = (CodeActionResolveSupportCapabilities) obj;
+    if (this.properties == null) {
+      if (other.properties != null)
+        return false;
+    } else if (!this.properties.equals(other.properties))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.properties== null) ? 0 : this.properties.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CodeLens.java b/java/org/eclipse/lsp4j/CodeLens.java
new file mode 100644
index 0000000..68ef8ae
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CodeLens.java
@@ -0,0 +1,155 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import com.google.gson.annotations.JsonAdapter;
+import org.eclipse.lsp4j.Command;
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A code lens represents a command that should be shown along with source text, like the number of references,
+ * a way to run tests, etc.
+ * <p>
+ * A code lens is <em>unresolved</em> when no command is associated to it. For performance reasons the creation of a
+ * code lens and resolving should be done to two stages.
+ */
+@SuppressWarnings("all")
+public class CodeLens {
+  /**
+   * The range in which this code lens is valid. Should only span a single line.
+   */
+  @NonNull
+  private Range range;
+  
+  /**
+   * The command this code lens represents.
+   */
+  private Command command;
+  
+  /**
+   * A data entry field that is preserved on a code lens item between a code lens and a code lens resolve request.
+   */
+  @JsonAdapter(JsonElementTypeAdapter.Factory.class)
+  private Object data;
+  
+  public CodeLens() {
+  }
+  
+  public CodeLens(@NonNull final Range range) {
+    this.range = Preconditions.<Range>checkNotNull(range, "range");
+  }
+  
+  public CodeLens(@NonNull final Range range, final Command command, final Object data) {
+    this(range);
+    this.command = command;
+    this.data = data;
+  }
+  
+  /**
+   * The range in which this code lens is valid. Should only span a single line.
+   */
+  @Pure
+  @NonNull
+  public Range getRange() {
+    return this.range;
+  }
+  
+  /**
+   * The range in which this code lens is valid. Should only span a single line.
+   */
+  public void setRange(@NonNull final Range range) {
+    this.range = Preconditions.checkNotNull(range, "range");
+  }
+  
+  /**
+   * The command this code lens represents.
+   */
+  @Pure
+  public Command getCommand() {
+    return this.command;
+  }
+  
+  /**
+   * The command this code lens represents.
+   */
+  public void setCommand(final Command command) {
+    this.command = command;
+  }
+  
+  /**
+   * A data entry field that is preserved on a code lens item between a code lens and a code lens resolve request.
+   */
+  @Pure
+  public Object getData() {
+    return this.data;
+  }
+  
+  /**
+   * A data entry field that is preserved on a code lens item between a code lens and a code lens resolve request.
+   */
+  public void setData(final Object data) {
+    this.data = data;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("range", this.range);
+    b.add("command", this.command);
+    b.add("data", this.data);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CodeLens other = (CodeLens) obj;
+    if (this.range == null) {
+      if (other.range != null)
+        return false;
+    } else if (!this.range.equals(other.range))
+      return false;
+    if (this.command == null) {
+      if (other.command != null)
+        return false;
+    } else if (!this.command.equals(other.command))
+      return false;
+    if (this.data == null) {
+      if (other.data != null)
+        return false;
+    } else if (!this.data.equals(other.data))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.range== null) ? 0 : this.range.hashCode());
+    result = prime * result + ((this.command== null) ? 0 : this.command.hashCode());
+    return prime * result + ((this.data== null) ? 0 : this.data.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CodeLensCapabilities.java b/java/org/eclipse/lsp4j/CodeLensCapabilities.java
new file mode 100644
index 0000000..6b30772
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CodeLensCapabilities.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the `textDocument/codeLens`
+ */
+@SuppressWarnings("all")
+public class CodeLensCapabilities extends DynamicRegistrationCapabilities {
+  public CodeLensCapabilities() {
+  }
+  
+  public CodeLensCapabilities(final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CodeLensOptions.java b/java/org/eclipse/lsp4j/CodeLensOptions.java
new file mode 100644
index 0000000..d951863
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CodeLensOptions.java
@@ -0,0 +1,84 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Code Lens options.
+ */
+@SuppressWarnings("all")
+public class CodeLensOptions extends AbstractWorkDoneProgressOptions {
+  /**
+   * Code lens has a resolve provider as well.
+   */
+  private Boolean resolveProvider;
+  
+  public CodeLensOptions() {
+  }
+  
+  public CodeLensOptions(final Boolean resolveProvider) {
+    this.resolveProvider = resolveProvider;
+  }
+  
+  /**
+   * Code lens has a resolve provider as well.
+   */
+  @Pure
+  public Boolean getResolveProvider() {
+    return this.resolveProvider;
+  }
+  
+  /**
+   * Code lens has a resolve provider as well.
+   */
+  public void setResolveProvider(final Boolean resolveProvider) {
+    this.resolveProvider = resolveProvider;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("resolveProvider", this.resolveProvider);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    CodeLensOptions other = (CodeLensOptions) obj;
+    if (this.resolveProvider == null) {
+      if (other.resolveProvider != null)
+        return false;
+    } else if (!this.resolveProvider.equals(other.resolveProvider))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.resolveProvider== null) ? 0 : this.resolveProvider.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CodeLensParams.java b/java/org/eclipse/lsp4j/CodeLensParams.java
new file mode 100644
index 0000000..3585bd7
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CodeLensParams.java
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.WorkDoneProgressAndPartialResultParams;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The code lens request is sent from the client to the server to compute code lenses for a given text document.
+ */
+@SuppressWarnings("all")
+public class CodeLensParams extends WorkDoneProgressAndPartialResultParams {
+  /**
+   * The document to request code lens for.
+   */
+  @NonNull
+  private TextDocumentIdentifier textDocument;
+  
+  public CodeLensParams() {
+  }
+  
+  public CodeLensParams(@NonNull final TextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.<TextDocumentIdentifier>checkNotNull(textDocument, "textDocument");
+  }
+  
+  /**
+   * The document to request code lens for.
+   */
+  @Pure
+  @NonNull
+  public TextDocumentIdentifier getTextDocument() {
+    return this.textDocument;
+  }
+  
+  /**
+   * The document to request code lens for.
+   */
+  public void setTextDocument(@NonNull final TextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.checkNotNull(textDocument, "textDocument");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("textDocument", this.textDocument);
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("partialResultToken", getPartialResultToken());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    CodeLensParams other = (CodeLensParams) obj;
+    if (this.textDocument == null) {
+      if (other.textDocument != null)
+        return false;
+    } else if (!this.textDocument.equals(other.textDocument))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.textDocument== null) ? 0 : this.textDocument.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CodeLensRegistrationOptions.java b/java/org/eclipse/lsp4j/CodeLensRegistrationOptions.java
new file mode 100644
index 0000000..96cc359
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CodeLensRegistrationOptions.java
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractTextDocumentRegistrationAndWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class CodeLensRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+  /**
+   * Code lens has a resolve provider as well.
+   */
+  private Boolean resolveProvider;
+  
+  public CodeLensRegistrationOptions() {
+  }
+  
+  public CodeLensRegistrationOptions(final Boolean resolveProvider) {
+    this.resolveProvider = resolveProvider;
+  }
+  
+  /**
+   * Code lens has a resolve provider as well.
+   */
+  @Pure
+  public Boolean getResolveProvider() {
+    return this.resolveProvider;
+  }
+  
+  /**
+   * Code lens has a resolve provider as well.
+   */
+  public void setResolveProvider(final Boolean resolveProvider) {
+    this.resolveProvider = resolveProvider;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("resolveProvider", this.resolveProvider);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    CodeLensRegistrationOptions other = (CodeLensRegistrationOptions) obj;
+    if (this.resolveProvider == null) {
+      if (other.resolveProvider != null)
+        return false;
+    } else if (!this.resolveProvider.equals(other.resolveProvider))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.resolveProvider== null) ? 0 : this.resolveProvider.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CodeLensWorkspaceCapabilities.java b/java/org/eclipse/lsp4j/CodeLensWorkspaceCapabilities.java
new file mode 100644
index 0000000..7353fc7
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CodeLensWorkspaceCapabilities.java
@@ -0,0 +1,101 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the code lens requests scoped to the
+ * workspace.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class CodeLensWorkspaceCapabilities {
+  /**
+   * Whether the client implementation supports a refresh request sent from the
+   * server to the client.
+   * <p>
+   * Note that this event is global and will force the client to refresh all
+   * code lenses currently shown. It should be used with absolute care and is
+   * useful for situations where a server for example detects a project-wide
+   * change that requires such a calculation.
+   */
+  private Boolean refreshSupport;
+  
+  public CodeLensWorkspaceCapabilities() {
+  }
+  
+  public CodeLensWorkspaceCapabilities(final Boolean refreshSupport) {
+    this.refreshSupport = refreshSupport;
+  }
+  
+  /**
+   * Whether the client implementation supports a refresh request sent from the
+   * server to the client.
+   * <p>
+   * Note that this event is global and will force the client to refresh all
+   * code lenses currently shown. It should be used with absolute care and is
+   * useful for situations where a server for example detects a project-wide
+   * change that requires such a calculation.
+   */
+  @Pure
+  public Boolean getRefreshSupport() {
+    return this.refreshSupport;
+  }
+  
+  /**
+   * Whether the client implementation supports a refresh request sent from the
+   * server to the client.
+   * <p>
+   * Note that this event is global and will force the client to refresh all
+   * code lenses currently shown. It should be used with absolute care and is
+   * useful for situations where a server for example detects a project-wide
+   * change that requires such a calculation.
+   */
+  public void setRefreshSupport(final Boolean refreshSupport) {
+    this.refreshSupport = refreshSupport;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("refreshSupport", this.refreshSupport);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CodeLensWorkspaceCapabilities other = (CodeLensWorkspaceCapabilities) obj;
+    if (this.refreshSupport == null) {
+      if (other.refreshSupport != null)
+        return false;
+    } else if (!this.refreshSupport.equals(other.refreshSupport))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.refreshSupport== null) ? 0 : this.refreshSupport.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/Color.java b/java/org/eclipse/lsp4j/Color.java
new file mode 100644
index 0000000..5ad37f8
--- /dev/null
+++ b/java/org/eclipse/lsp4j/Color.java
@@ -0,0 +1,154 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Represents a color in RGBA space.
+ */
+@SuppressWarnings("all")
+public class Color {
+  /**
+   * The red component of this color in the range [0-1].
+   */
+  private double red;
+  
+  /**
+   * The green component of this color in the range [0-1].
+   */
+  private double green;
+  
+  /**
+   * The blue component of this color in the range [0-1].
+   */
+  private double blue;
+  
+  /**
+   * The alpha component of this color in the range [0-1].
+   */
+  private double alpha;
+  
+  public Color() {
+  }
+  
+  public Color(final double red, final double green, final double blue, final double alpha) {
+    this.red = red;
+    this.green = green;
+    this.blue = blue;
+    this.alpha = alpha;
+  }
+  
+  /**
+   * The red component of this color in the range [0-1].
+   */
+  @Pure
+  public double getRed() {
+    return this.red;
+  }
+  
+  /**
+   * The red component of this color in the range [0-1].
+   */
+  public void setRed(final double red) {
+    this.red = red;
+  }
+  
+  /**
+   * The green component of this color in the range [0-1].
+   */
+  @Pure
+  public double getGreen() {
+    return this.green;
+  }
+  
+  /**
+   * The green component of this color in the range [0-1].
+   */
+  public void setGreen(final double green) {
+    this.green = green;
+  }
+  
+  /**
+   * The blue component of this color in the range [0-1].
+   */
+  @Pure
+  public double getBlue() {
+    return this.blue;
+  }
+  
+  /**
+   * The blue component of this color in the range [0-1].
+   */
+  public void setBlue(final double blue) {
+    this.blue = blue;
+  }
+  
+  /**
+   * The alpha component of this color in the range [0-1].
+   */
+  @Pure
+  public double getAlpha() {
+    return this.alpha;
+  }
+  
+  /**
+   * The alpha component of this color in the range [0-1].
+   */
+  public void setAlpha(final double alpha) {
+    this.alpha = alpha;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("red", this.red);
+    b.add("green", this.green);
+    b.add("blue", this.blue);
+    b.add("alpha", this.alpha);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    Color other = (Color) obj;
+    if (Double.doubleToLongBits(other.red) != Double.doubleToLongBits(this.red))
+      return false; 
+    if (Double.doubleToLongBits(other.green) != Double.doubleToLongBits(this.green))
+      return false; 
+    if (Double.doubleToLongBits(other.blue) != Double.doubleToLongBits(this.blue))
+      return false; 
+    if (Double.doubleToLongBits(other.alpha) != Double.doubleToLongBits(this.alpha))
+      return false; 
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + (int) (Double.doubleToLongBits(this.red) ^ (Double.doubleToLongBits(this.red) >>> 32));
+    result = prime * result + (int) (Double.doubleToLongBits(this.green) ^ (Double.doubleToLongBits(this.green) >>> 32));
+    result = prime * result + (int) (Double.doubleToLongBits(this.blue) ^ (Double.doubleToLongBits(this.blue) >>> 32));
+    return prime * result + (int) (Double.doubleToLongBits(this.alpha) ^ (Double.doubleToLongBits(this.alpha) >>> 32));
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ColorInformation.java b/java/org/eclipse/lsp4j/ColorInformation.java
new file mode 100644
index 0000000..d5d742d
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ColorInformation.java
@@ -0,0 +1,115 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.Color;
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class ColorInformation {
+  /**
+   * The range in the document where this color appears.
+   */
+  @NonNull
+  private Range range;
+  
+  /**
+   * The actual color value for this color range.
+   */
+  @NonNull
+  private Color color;
+  
+  public ColorInformation() {
+  }
+  
+  public ColorInformation(@NonNull final Range range, @NonNull final Color color) {
+    this.range = Preconditions.<Range>checkNotNull(range, "range");
+    this.color = Preconditions.<Color>checkNotNull(color, "color");
+  }
+  
+  /**
+   * The range in the document where this color appears.
+   */
+  @Pure
+  @NonNull
+  public Range getRange() {
+    return this.range;
+  }
+  
+  /**
+   * The range in the document where this color appears.
+   */
+  public void setRange(@NonNull final Range range) {
+    this.range = Preconditions.checkNotNull(range, "range");
+  }
+  
+  /**
+   * The actual color value for this color range.
+   */
+  @Pure
+  @NonNull
+  public Color getColor() {
+    return this.color;
+  }
+  
+  /**
+   * The actual color value for this color range.
+   */
+  public void setColor(@NonNull final Color color) {
+    this.color = Preconditions.checkNotNull(color, "color");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("range", this.range);
+    b.add("color", this.color);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ColorInformation other = (ColorInformation) obj;
+    if (this.range == null) {
+      if (other.range != null)
+        return false;
+    } else if (!this.range.equals(other.range))
+      return false;
+    if (this.color == null) {
+      if (other.color != null)
+        return false;
+    } else if (!this.color.equals(other.color))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.range== null) ? 0 : this.range.hashCode());
+    return prime * result + ((this.color== null) ? 0 : this.color.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ColorPresentation.java b/java/org/eclipse/lsp4j/ColorPresentation.java
new file mode 100644
index 0000000..6703a85
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ColorPresentation.java
@@ -0,0 +1,162 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.TextEdit;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class ColorPresentation {
+  /**
+   * The label of this color presentation. It will be shown on the color
+   * picker header. By default this is also the text that is inserted when selecting
+   * this color presentation.
+   */
+  @NonNull
+  private String label;
+  
+  /**
+   * An edit which is applied to a document when selecting
+   * this presentation for the color. When `null` the label is used.
+   */
+  private TextEdit textEdit;
+  
+  /**
+   * An optional array of additional text edits that are applied when
+   * selecting this color presentation. Edits must not overlap with the main edit nor with themselves.
+   */
+  private List<TextEdit> additionalTextEdits;
+  
+  public ColorPresentation() {
+  }
+  
+  public ColorPresentation(@NonNull final String label) {
+    this.label = Preconditions.<String>checkNotNull(label, "label");
+  }
+  
+  public ColorPresentation(@NonNull final String label, final TextEdit textEdit) {
+    this(label);
+    this.textEdit = textEdit;
+  }
+  
+  public ColorPresentation(@NonNull final String label, final TextEdit textEdit, final List<TextEdit> additionalTextEdits) {
+    this(label);
+    this.textEdit = textEdit;
+    this.additionalTextEdits = additionalTextEdits;
+  }
+  
+  /**
+   * The label of this color presentation. It will be shown on the color
+   * picker header. By default this is also the text that is inserted when selecting
+   * this color presentation.
+   */
+  @Pure
+  @NonNull
+  public String getLabel() {
+    return this.label;
+  }
+  
+  /**
+   * The label of this color presentation. It will be shown on the color
+   * picker header. By default this is also the text that is inserted when selecting
+   * this color presentation.
+   */
+  public void setLabel(@NonNull final String label) {
+    this.label = Preconditions.checkNotNull(label, "label");
+  }
+  
+  /**
+   * An edit which is applied to a document when selecting
+   * this presentation for the color. When `null` the label is used.
+   */
+  @Pure
+  public TextEdit getTextEdit() {
+    return this.textEdit;
+  }
+  
+  /**
+   * An edit which is applied to a document when selecting
+   * this presentation for the color. When `null` the label is used.
+   */
+  public void setTextEdit(final TextEdit textEdit) {
+    this.textEdit = textEdit;
+  }
+  
+  /**
+   * An optional array of additional text edits that are applied when
+   * selecting this color presentation. Edits must not overlap with the main edit nor with themselves.
+   */
+  @Pure
+  public List<TextEdit> getAdditionalTextEdits() {
+    return this.additionalTextEdits;
+  }
+  
+  /**
+   * An optional array of additional text edits that are applied when
+   * selecting this color presentation. Edits must not overlap with the main edit nor with themselves.
+   */
+  public void setAdditionalTextEdits(final List<TextEdit> additionalTextEdits) {
+    this.additionalTextEdits = additionalTextEdits;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("label", this.label);
+    b.add("textEdit", this.textEdit);
+    b.add("additionalTextEdits", this.additionalTextEdits);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ColorPresentation other = (ColorPresentation) obj;
+    if (this.label == null) {
+      if (other.label != null)
+        return false;
+    } else if (!this.label.equals(other.label))
+      return false;
+    if (this.textEdit == null) {
+      if (other.textEdit != null)
+        return false;
+    } else if (!this.textEdit.equals(other.textEdit))
+      return false;
+    if (this.additionalTextEdits == null) {
+      if (other.additionalTextEdits != null)
+        return false;
+    } else if (!this.additionalTextEdits.equals(other.additionalTextEdits))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.label== null) ? 0 : this.label.hashCode());
+    result = prime * result + ((this.textEdit== null) ? 0 : this.textEdit.hashCode());
+    return prime * result + ((this.additionalTextEdits== null) ? 0 : this.additionalTextEdits.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ColorPresentationParams.java b/java/org/eclipse/lsp4j/ColorPresentationParams.java
new file mode 100644
index 0000000..3e6f5b1
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ColorPresentationParams.java
@@ -0,0 +1,157 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.Color;
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.WorkDoneProgressAndPartialResultParams;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The color presentation request is sent from the client to the server to obtain a list of presentations
+ * for a color value at a given location.
+ * <p>
+ * Since 3.6.0
+ */
+@SuppressWarnings("all")
+public class ColorPresentationParams extends WorkDoneProgressAndPartialResultParams {
+  /**
+   * The text document.
+   */
+  @NonNull
+  private TextDocumentIdentifier textDocument;
+  
+  /**
+   * The color information to request presentations for.
+   */
+  @NonNull
+  private Color color;
+  
+  /**
+   * The range where the color would be inserted. Serves as a context.
+   */
+  @NonNull
+  private Range range;
+  
+  public ColorPresentationParams() {
+  }
+  
+  public ColorPresentationParams(@NonNull final TextDocumentIdentifier textDocument, @NonNull final Color color, @NonNull final Range range) {
+    this.textDocument = Preconditions.<TextDocumentIdentifier>checkNotNull(textDocument, "textDocument");
+    this.color = Preconditions.<Color>checkNotNull(color, "color");
+    this.range = Preconditions.<Range>checkNotNull(range, "range");
+  }
+  
+  /**
+   * The text document.
+   */
+  @Pure
+  @NonNull
+  public TextDocumentIdentifier getTextDocument() {
+    return this.textDocument;
+  }
+  
+  /**
+   * The text document.
+   */
+  public void setTextDocument(@NonNull final TextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.checkNotNull(textDocument, "textDocument");
+  }
+  
+  /**
+   * The color information to request presentations for.
+   */
+  @Pure
+  @NonNull
+  public Color getColor() {
+    return this.color;
+  }
+  
+  /**
+   * The color information to request presentations for.
+   */
+  public void setColor(@NonNull final Color color) {
+    this.color = Preconditions.checkNotNull(color, "color");
+  }
+  
+  /**
+   * The range where the color would be inserted. Serves as a context.
+   */
+  @Pure
+  @NonNull
+  public Range getRange() {
+    return this.range;
+  }
+  
+  /**
+   * The range where the color would be inserted. Serves as a context.
+   */
+  public void setRange(@NonNull final Range range) {
+    this.range = Preconditions.checkNotNull(range, "range");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("textDocument", this.textDocument);
+    b.add("color", this.color);
+    b.add("range", this.range);
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("partialResultToken", getPartialResultToken());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    ColorPresentationParams other = (ColorPresentationParams) obj;
+    if (this.textDocument == null) {
+      if (other.textDocument != null)
+        return false;
+    } else if (!this.textDocument.equals(other.textDocument))
+      return false;
+    if (this.color == null) {
+      if (other.color != null)
+        return false;
+    } else if (!this.color.equals(other.color))
+      return false;
+    if (this.range == null) {
+      if (other.range != null)
+        return false;
+    } else if (!this.range.equals(other.range))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.textDocument== null) ? 0 : this.textDocument.hashCode());
+    result = prime * result + ((this.color== null) ? 0 : this.color.hashCode());
+    return prime * result + ((this.range== null) ? 0 : this.range.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ColorProviderCapabilities.java b/java/org/eclipse/lsp4j/ColorProviderCapabilities.java
new file mode 100644
index 0000000..9c9447f
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ColorProviderCapabilities.java
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the `textDocument/documentColor` and the
+ * `textDocument/colorPresentation` request.
+ * <p>
+ * Since 3.6.0
+ */
+@SuppressWarnings("all")
+public class ColorProviderCapabilities extends DynamicRegistrationCapabilities {
+  public ColorProviderCapabilities() {
+  }
+  
+  public ColorProviderCapabilities(final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ColorProviderOptions.java b/java/org/eclipse/lsp4j/ColorProviderOptions.java
new file mode 100644
index 0000000..642459c
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ColorProviderOptions.java
@@ -0,0 +1,88 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractTextDocumentRegistrationAndWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Document color options
+ */
+@SuppressWarnings("all")
+public class ColorProviderOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  private String id;
+  
+  public ColorProviderOptions() {
+  }
+  
+  public ColorProviderOptions(final String id) {
+    this.id = id;
+  }
+  
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  @Pure
+  public String getId() {
+    return this.id;
+  }
+  
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  public void setId(final String id) {
+    this.id = id;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("id", this.id);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    ColorProviderOptions other = (ColorProviderOptions) obj;
+    if (this.id == null) {
+      if (other.id != null)
+        return false;
+    } else if (!this.id.equals(other.id))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.id== null) ? 0 : this.id.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/Command.java b/java/org/eclipse/lsp4j/Command.java
new file mode 100644
index 0000000..1a8bed0
--- /dev/null
+++ b/java/org/eclipse/lsp4j/Command.java
@@ -0,0 +1,150 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Represents a reference to a command. Provides a title which will be used to represent a command in the UI and,
+ * optionally, an array of arguments which will be passed to the command handler function when invoked.
+ */
+@SuppressWarnings("all")
+public class Command {
+  /**
+   * Title of the command, like `save`.
+   */
+  @NonNull
+  private String title;
+  
+  /**
+   * The identifier of the actual command handler.
+   */
+  @NonNull
+  private String command;
+  
+  /**
+   * Arguments that the command handler should be invoked with.
+   */
+  private List<Object> arguments;
+  
+  public Command() {
+  }
+  
+  public Command(@NonNull final String title, @NonNull final String command) {
+    this.title = Preconditions.<String>checkNotNull(title, "title");
+    this.command = Preconditions.<String>checkNotNull(command, "command");
+  }
+  
+  public Command(@NonNull final String title, @NonNull final String command, final List<Object> arguments) {
+    this(title, command);
+    this.arguments = arguments;
+  }
+  
+  /**
+   * Title of the command, like `save`.
+   */
+  @Pure
+  @NonNull
+  public String getTitle() {
+    return this.title;
+  }
+  
+  /**
+   * Title of the command, like `save`.
+   */
+  public void setTitle(@NonNull final String title) {
+    this.title = Preconditions.checkNotNull(title, "title");
+  }
+  
+  /**
+   * The identifier of the actual command handler.
+   */
+  @Pure
+  @NonNull
+  public String getCommand() {
+    return this.command;
+  }
+  
+  /**
+   * The identifier of the actual command handler.
+   */
+  public void setCommand(@NonNull final String command) {
+    this.command = Preconditions.checkNotNull(command, "command");
+  }
+  
+  /**
+   * Arguments that the command handler should be invoked with.
+   */
+  @Pure
+  public List<Object> getArguments() {
+    return this.arguments;
+  }
+  
+  /**
+   * Arguments that the command handler should be invoked with.
+   */
+  public void setArguments(final List<Object> arguments) {
+    this.arguments = arguments;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("title", this.title);
+    b.add("command", this.command);
+    b.add("arguments", this.arguments);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    Command other = (Command) obj;
+    if (this.title == null) {
+      if (other.title != null)
+        return false;
+    } else if (!this.title.equals(other.title))
+      return false;
+    if (this.command == null) {
+      if (other.command != null)
+        return false;
+    } else if (!this.command.equals(other.command))
+      return false;
+    if (this.arguments == null) {
+      if (other.arguments != null)
+        return false;
+    } else if (!this.arguments.equals(other.arguments))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.title== null) ? 0 : this.title.hashCode());
+    result = prime * result + ((this.command== null) ? 0 : this.command.hashCode());
+    return prime * result + ((this.arguments== null) ? 0 : this.arguments.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CompletionCapabilities.java b/java/org/eclipse/lsp4j/CompletionCapabilities.java
new file mode 100644
index 0000000..cf81ce4
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CompletionCapabilities.java
@@ -0,0 +1,159 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.CompletionItemCapabilities;
+import org.eclipse.lsp4j.CompletionItemKindCapabilities;
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the `textDocument/completion`
+ */
+@SuppressWarnings("all")
+public class CompletionCapabilities extends DynamicRegistrationCapabilities {
+  /**
+   * The client supports the following {@link CompletionItem} specific
+   * capabilities.
+   */
+  private CompletionItemCapabilities completionItem;
+  
+  /**
+   * The client supports the following {@link CompletionItemKind} specific
+   * capabilities.
+   */
+  private CompletionItemKindCapabilities completionItemKind;
+  
+  /**
+   * The client supports sending additional context information for a
+   * `textDocument/completion` request.
+   */
+  private Boolean contextSupport;
+  
+  public CompletionCapabilities() {
+  }
+  
+  public CompletionCapabilities(final CompletionItemCapabilities completionItem) {
+    this.completionItem = completionItem;
+  }
+  
+  public CompletionCapabilities(final CompletionItemKindCapabilities completionItemKind) {
+    this.completionItemKind = completionItemKind;
+  }
+  
+  public CompletionCapabilities(final Boolean contextSupport) {
+    this.contextSupport = contextSupport;
+  }
+  
+  /**
+   * The client supports the following {@link CompletionItem} specific
+   * capabilities.
+   */
+  @Pure
+  public CompletionItemCapabilities getCompletionItem() {
+    return this.completionItem;
+  }
+  
+  /**
+   * The client supports the following {@link CompletionItem} specific
+   * capabilities.
+   */
+  public void setCompletionItem(final CompletionItemCapabilities completionItem) {
+    this.completionItem = completionItem;
+  }
+  
+  /**
+   * The client supports the following {@link CompletionItemKind} specific
+   * capabilities.
+   */
+  @Pure
+  public CompletionItemKindCapabilities getCompletionItemKind() {
+    return this.completionItemKind;
+  }
+  
+  /**
+   * The client supports the following {@link CompletionItemKind} specific
+   * capabilities.
+   */
+  public void setCompletionItemKind(final CompletionItemKindCapabilities completionItemKind) {
+    this.completionItemKind = completionItemKind;
+  }
+  
+  /**
+   * The client supports sending additional context information for a
+   * `textDocument/completion` request.
+   */
+  @Pure
+  public Boolean getContextSupport() {
+    return this.contextSupport;
+  }
+  
+  /**
+   * The client supports sending additional context information for a
+   * `textDocument/completion` request.
+   */
+  public void setContextSupport(final Boolean contextSupport) {
+    this.contextSupport = contextSupport;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("completionItem", this.completionItem);
+    b.add("completionItemKind", this.completionItemKind);
+    b.add("contextSupport", this.contextSupport);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    CompletionCapabilities other = (CompletionCapabilities) obj;
+    if (this.completionItem == null) {
+      if (other.completionItem != null)
+        return false;
+    } else if (!this.completionItem.equals(other.completionItem))
+      return false;
+    if (this.completionItemKind == null) {
+      if (other.completionItemKind != null)
+        return false;
+    } else if (!this.completionItemKind.equals(other.completionItemKind))
+      return false;
+    if (this.contextSupport == null) {
+      if (other.contextSupport != null)
+        return false;
+    } else if (!this.contextSupport.equals(other.contextSupport))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.completionItem== null) ? 0 : this.completionItem.hashCode());
+    result = prime * result + ((this.completionItemKind== null) ? 0 : this.completionItemKind.hashCode());
+    return prime * result + ((this.contextSupport== null) ? 0 : this.contextSupport.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CompletionContext.java b/java/org/eclipse/lsp4j/CompletionContext.java
new file mode 100644
index 0000000..f4db969
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CompletionContext.java
@@ -0,0 +1,119 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.CompletionTriggerKind;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class CompletionContext {
+  /**
+   * How the completion was triggered.
+   */
+  @NonNull
+  private CompletionTriggerKind triggerKind;
+  
+  /**
+   * The trigger character (a single character) that has trigger code complete.
+   * Is undefined if {@link #triggerKind} is not {@link CompletionTriggerKind#TriggerCharacter}.
+   */
+  private String triggerCharacter;
+  
+  public CompletionContext() {
+  }
+  
+  public CompletionContext(@NonNull final CompletionTriggerKind triggerKind) {
+    this.triggerKind = Preconditions.<CompletionTriggerKind>checkNotNull(triggerKind, "triggerKind");
+  }
+  
+  public CompletionContext(@NonNull final CompletionTriggerKind triggerKind, final String triggerCharacter) {
+    this(triggerKind);
+    this.triggerCharacter = triggerCharacter;
+  }
+  
+  /**
+   * How the completion was triggered.
+   */
+  @Pure
+  @NonNull
+  public CompletionTriggerKind getTriggerKind() {
+    return this.triggerKind;
+  }
+  
+  /**
+   * How the completion was triggered.
+   */
+  public void setTriggerKind(@NonNull final CompletionTriggerKind triggerKind) {
+    this.triggerKind = Preconditions.checkNotNull(triggerKind, "triggerKind");
+  }
+  
+  /**
+   * The trigger character (a single character) that has trigger code complete.
+   * Is undefined if {@link #triggerKind} is not {@link CompletionTriggerKind#TriggerCharacter}.
+   */
+  @Pure
+  public String getTriggerCharacter() {
+    return this.triggerCharacter;
+  }
+  
+  /**
+   * The trigger character (a single character) that has trigger code complete.
+   * Is undefined if {@link #triggerKind} is not {@link CompletionTriggerKind#TriggerCharacter}.
+   */
+  public void setTriggerCharacter(final String triggerCharacter) {
+    this.triggerCharacter = triggerCharacter;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("triggerKind", this.triggerKind);
+    b.add("triggerCharacter", this.triggerCharacter);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CompletionContext other = (CompletionContext) obj;
+    if (this.triggerKind == null) {
+      if (other.triggerKind != null)
+        return false;
+    } else if (!this.triggerKind.equals(other.triggerKind))
+      return false;
+    if (this.triggerCharacter == null) {
+      if (other.triggerCharacter != null)
+        return false;
+    } else if (!this.triggerCharacter.equals(other.triggerCharacter))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.triggerKind== null) ? 0 : this.triggerKind.hashCode());
+    return prime * result + ((this.triggerCharacter== null) ? 0 : this.triggerCharacter.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CompletionItem.java b/java/org/eclipse/lsp4j/CompletionItem.java
new file mode 100644
index 0000000..7909b4f
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CompletionItem.java
@@ -0,0 +1,687 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import com.google.gson.annotations.JsonAdapter;
+import java.util.List;
+import org.eclipse.lsp4j.Command;
+import org.eclipse.lsp4j.CompletionItemKind;
+import org.eclipse.lsp4j.CompletionItemTag;
+import org.eclipse.lsp4j.InsertReplaceEdit;
+import org.eclipse.lsp4j.InsertTextFormat;
+import org.eclipse.lsp4j.InsertTextMode;
+import org.eclipse.lsp4j.MarkupContent;
+import org.eclipse.lsp4j.TextEdit;
+import org.eclipse.lsp4j.adapters.CompletionItemTextEditTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The Completion request is sent from the client to the server to compute completion items at a given cursor position.
+ * Completion items are presented in the IntelliSense user class. If computing complete completion items is expensive
+ * servers can additional provide a handler for the resolve completion item request. This request is send when a
+ * completion item is selected in the user class.
+ */
+@SuppressWarnings("all")
+public class CompletionItem {
+  /**
+   * The label of this completion item. By default also the text that is inserted when selecting this completion.
+   */
+  @NonNull
+  private String label;
+  
+  /**
+   * The kind of this completion item. Based of the kind an icon is chosen by the editor.
+   */
+  private CompletionItemKind kind;
+  
+  /**
+   * Tags for this completion item.
+   * <p>
+   * Since 3.15.0
+   */
+  private List<CompletionItemTag> tags;
+  
+  /**
+   * A human-readable string with additional information about this item, like type or symbol information.
+   */
+  private String detail;
+  
+  /**
+   * A human-readable string that represents a doc-comment.
+   */
+  private Either<String, MarkupContent> documentation;
+  
+  /**
+   * Indicates if this item is deprecated.
+   * 
+   * @deprecated Use {@link #tags} instead if supported.
+   */
+  @Deprecated
+  private Boolean deprecated;
+  
+  /**
+   * Select this item when showing.
+   * <p>
+   * <em>Note</em> that only one completion item can be selected and that the
+   * tool / client decides which item that is. The rule is that the <em>first</em>
+   * item of those that match best is selected.
+   */
+  private Boolean preselect;
+  
+  /**
+   * A string that should be used when comparing this item with other items. When `falsy` the label is used.
+   */
+  private String sortText;
+  
+  /**
+   * A string that should be used when filtering a set of completion items. When `falsy` the label is used.
+   */
+  private String filterText;
+  
+  /**
+   * A string that should be inserted a document when selecting this completion. When `falsy` the label is used.
+   */
+  private String insertText;
+  
+  /**
+   * The format of the insert text. The format applies to both the {@link #insertText} property
+   * and the {@code newText} property of a provided {@link #textEdit}.
+   */
+  private InsertTextFormat insertTextFormat;
+  
+  /**
+   * How whitespace and indentation is handled during completion item
+   * insertion. If not provided, the client's default value is used.
+   * <p>
+   * Since 3.16.0
+   */
+  private InsertTextMode insertTextMode;
+  
+  /**
+   * An edit which is applied to a document when selecting this completion.
+   * When an edit is provided the value of {@link #insertText} is ignored.
+   * <p>
+   * <em>Note:</em> The range of the edit must be a single line range and it must
+   * contain the position at which completion has been requested.
+   * <p>
+   * Most editors support two different operations when accepting a completion
+   * item. One is to insert a completion text and the other is to replace an
+   * existing text with a completion text. Since this can usually not be
+   * predetermined by a server it can report both ranges. Clients need to
+   * signal support for {@link InsertReplaceEdit}s via the
+   * {@link CompletionItemCapabilities#insertReplaceSupport} client capability
+   * property.
+   * <p>
+   * <em>Note 1:</em> The text edit's range as well as both ranges from an insert
+   * replace edit must be a [single line] and they must contain the position
+   * at which completion has been requested.
+   * <p>
+   * <em>Note 2:</em> If an {@link InsertReplaceEdit} is returned the edit's insert range
+   * must be a prefix of the edit's replace range, that means it must be
+   * contained and starting at the same position.
+   * <p>
+   * Since 3.16.0 additional type {@link InsertReplaceEdit}
+   */
+  @JsonAdapter(CompletionItemTextEditTypeAdapter.class)
+  private Either<TextEdit, InsertReplaceEdit> textEdit;
+  
+  /**
+   * An optional array of additional text edits that are applied when
+   * selecting this completion. Edits must not overlap (including the same insert position)
+   * with the main edit nor with themselves.
+   * <p>
+   * Additional text edits should be used to change text unrelated to the current cursor position
+   * (for example adding an import statement at the top of the file if the completion item will
+   * insert an unqualified type).
+   */
+  private List<TextEdit> additionalTextEdits;
+  
+  /**
+   * An optional set of characters that when pressed while this completion is active will accept it first and
+   * then type that character. <em>Note</em> that all commit characters should have {@code length=1} and that superfluous
+   * characters will be ignored.
+   */
+  private List<String> commitCharacters;
+  
+  /**
+   * An optional command that is executed <em>after</em> inserting this completion. <em>Note</em> that
+   * additional modifications to the current document should be described with the
+   * {@link #additionalTextEdits} property.
+   */
+  private Command command;
+  
+  /**
+   * A data entry field that is preserved on a completion item between a completion and a completion resolve request.
+   */
+  @JsonAdapter(JsonElementTypeAdapter.Factory.class)
+  private Object data;
+  
+  public CompletionItem() {
+  }
+  
+  public CompletionItem(@NonNull final String label) {
+    this.label = Preconditions.<String>checkNotNull(label, "label");
+  }
+  
+  /**
+   * The label of this completion item. By default also the text that is inserted when selecting this completion.
+   */
+  @Pure
+  @NonNull
+  public String getLabel() {
+    return this.label;
+  }
+  
+  /**
+   * The label of this completion item. By default also the text that is inserted when selecting this completion.
+   */
+  public void setLabel(@NonNull final String label) {
+    this.label = Preconditions.checkNotNull(label, "label");
+  }
+  
+  /**
+   * The kind of this completion item. Based of the kind an icon is chosen by the editor.
+   */
+  @Pure
+  public CompletionItemKind getKind() {
+    return this.kind;
+  }
+  
+  /**
+   * The kind of this completion item. Based of the kind an icon is chosen by the editor.
+   */
+  public void setKind(final CompletionItemKind kind) {
+    this.kind = kind;
+  }
+  
+  /**
+   * Tags for this completion item.
+   * <p>
+   * Since 3.15.0
+   */
+  @Pure
+  public List<CompletionItemTag> getTags() {
+    return this.tags;
+  }
+  
+  /**
+   * Tags for this completion item.
+   * <p>
+   * Since 3.15.0
+   */
+  public void setTags(final List<CompletionItemTag> tags) {
+    this.tags = tags;
+  }
+  
+  /**
+   * A human-readable string with additional information about this item, like type or symbol information.
+   */
+  @Pure
+  public String getDetail() {
+    return this.detail;
+  }
+  
+  /**
+   * A human-readable string with additional information about this item, like type or symbol information.
+   */
+  public void setDetail(final String detail) {
+    this.detail = detail;
+  }
+  
+  /**
+   * A human-readable string that represents a doc-comment.
+   */
+  @Pure
+  public Either<String, MarkupContent> getDocumentation() {
+    return this.documentation;
+  }
+  
+  /**
+   * A human-readable string that represents a doc-comment.
+   */
+  public void setDocumentation(final Either<String, MarkupContent> documentation) {
+    this.documentation = documentation;
+  }
+  
+  public void setDocumentation(final String documentation) {
+    if (documentation == null) {
+      this.documentation = null;
+      return;
+    }
+    this.documentation = Either.forLeft(documentation);
+  }
+  
+  public void setDocumentation(final MarkupContent documentation) {
+    if (documentation == null) {
+      this.documentation = null;
+      return;
+    }
+    this.documentation = Either.forRight(documentation);
+  }
+  
+  /**
+   * Indicates if this item is deprecated.
+   * 
+   * @deprecated Use {@link #tags} instead if supported.
+   */
+  @Pure
+  @Deprecated
+  public Boolean getDeprecated() {
+    return this.deprecated;
+  }
+  
+  /**
+   * Indicates if this item is deprecated.
+   * 
+   * @deprecated Use {@link #tags} instead if supported.
+   */
+  @Deprecated
+  public void setDeprecated(final Boolean deprecated) {
+    this.deprecated = deprecated;
+  }
+  
+  /**
+   * Select this item when showing.
+   * <p>
+   * <em>Note</em> that only one completion item can be selected and that the
+   * tool / client decides which item that is. The rule is that the <em>first</em>
+   * item of those that match best is selected.
+   */
+  @Pure
+  public Boolean getPreselect() {
+    return this.preselect;
+  }
+  
+  /**
+   * Select this item when showing.
+   * <p>
+   * <em>Note</em> that only one completion item can be selected and that the
+   * tool / client decides which item that is. The rule is that the <em>first</em>
+   * item of those that match best is selected.
+   */
+  public void setPreselect(final Boolean preselect) {
+    this.preselect = preselect;
+  }
+  
+  /**
+   * A string that should be used when comparing this item with other items. When `falsy` the label is used.
+   */
+  @Pure
+  public String getSortText() {
+    return this.sortText;
+  }
+  
+  /**
+   * A string that should be used when comparing this item with other items. When `falsy` the label is used.
+   */
+  public void setSortText(final String sortText) {
+    this.sortText = sortText;
+  }
+  
+  /**
+   * A string that should be used when filtering a set of completion items. When `falsy` the label is used.
+   */
+  @Pure
+  public String getFilterText() {
+    return this.filterText;
+  }
+  
+  /**
+   * A string that should be used when filtering a set of completion items. When `falsy` the label is used.
+   */
+  public void setFilterText(final String filterText) {
+    this.filterText = filterText;
+  }
+  
+  /**
+   * A string that should be inserted a document when selecting this completion. When `falsy` the label is used.
+   */
+  @Pure
+  public String getInsertText() {
+    return this.insertText;
+  }
+  
+  /**
+   * A string that should be inserted a document when selecting this completion. When `falsy` the label is used.
+   */
+  public void setInsertText(final String insertText) {
+    this.insertText = insertText;
+  }
+  
+  /**
+   * The format of the insert text. The format applies to both the {@link #insertText} property
+   * and the {@code newText} property of a provided {@link #textEdit}.
+   */
+  @Pure
+  public InsertTextFormat getInsertTextFormat() {
+    return this.insertTextFormat;
+  }
+  
+  /**
+   * The format of the insert text. The format applies to both the {@link #insertText} property
+   * and the {@code newText} property of a provided {@link #textEdit}.
+   */
+  public void setInsertTextFormat(final InsertTextFormat insertTextFormat) {
+    this.insertTextFormat = insertTextFormat;
+  }
+  
+  /**
+   * How whitespace and indentation is handled during completion item
+   * insertion. If not provided, the client's default value is used.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public InsertTextMode getInsertTextMode() {
+    return this.insertTextMode;
+  }
+  
+  /**
+   * How whitespace and indentation is handled during completion item
+   * insertion. If not provided, the client's default value is used.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setInsertTextMode(final InsertTextMode insertTextMode) {
+    this.insertTextMode = insertTextMode;
+  }
+  
+  /**
+   * An edit which is applied to a document when selecting this completion.
+   * When an edit is provided the value of {@link #insertText} is ignored.
+   * <p>
+   * <em>Note:</em> The range of the edit must be a single line range and it must
+   * contain the position at which completion has been requested.
+   * <p>
+   * Most editors support two different operations when accepting a completion
+   * item. One is to insert a completion text and the other is to replace an
+   * existing text with a completion text. Since this can usually not be
+   * predetermined by a server it can report both ranges. Clients need to
+   * signal support for {@link InsertReplaceEdit}s via the
+   * {@link CompletionItemCapabilities#insertReplaceSupport} client capability
+   * property.
+   * <p>
+   * <em>Note 1:</em> The text edit's range as well as both ranges from an insert
+   * replace edit must be a [single line] and they must contain the position
+   * at which completion has been requested.
+   * <p>
+   * <em>Note 2:</em> If an {@link InsertReplaceEdit} is returned the edit's insert range
+   * must be a prefix of the edit's replace range, that means it must be
+   * contained and starting at the same position.
+   * <p>
+   * Since 3.16.0 additional type {@link InsertReplaceEdit}
+   */
+  @Pure
+  public Either<TextEdit, InsertReplaceEdit> getTextEdit() {
+    return this.textEdit;
+  }
+  
+  /**
+   * An edit which is applied to a document when selecting this completion.
+   * When an edit is provided the value of {@link #insertText} is ignored.
+   * <p>
+   * <em>Note:</em> The range of the edit must be a single line range and it must
+   * contain the position at which completion has been requested.
+   * <p>
+   * Most editors support two different operations when accepting a completion
+   * item. One is to insert a completion text and the other is to replace an
+   * existing text with a completion text. Since this can usually not be
+   * predetermined by a server it can report both ranges. Clients need to
+   * signal support for {@link InsertReplaceEdit}s via the
+   * {@link CompletionItemCapabilities#insertReplaceSupport} client capability
+   * property.
+   * <p>
+   * <em>Note 1:</em> The text edit's range as well as both ranges from an insert
+   * replace edit must be a [single line] and they must contain the position
+   * at which completion has been requested.
+   * <p>
+   * <em>Note 2:</em> If an {@link InsertReplaceEdit} is returned the edit's insert range
+   * must be a prefix of the edit's replace range, that means it must be
+   * contained and starting at the same position.
+   * <p>
+   * Since 3.16.0 additional type {@link InsertReplaceEdit}
+   */
+  public void setTextEdit(final Either<TextEdit, InsertReplaceEdit> textEdit) {
+    this.textEdit = textEdit;
+  }
+  
+  /**
+   * An optional array of additional text edits that are applied when
+   * selecting this completion. Edits must not overlap (including the same insert position)
+   * with the main edit nor with themselves.
+   * <p>
+   * Additional text edits should be used to change text unrelated to the current cursor position
+   * (for example adding an import statement at the top of the file if the completion item will
+   * insert an unqualified type).
+   */
+  @Pure
+  public List<TextEdit> getAdditionalTextEdits() {
+    return this.additionalTextEdits;
+  }
+  
+  /**
+   * An optional array of additional text edits that are applied when
+   * selecting this completion. Edits must not overlap (including the same insert position)
+   * with the main edit nor with themselves.
+   * <p>
+   * Additional text edits should be used to change text unrelated to the current cursor position
+   * (for example adding an import statement at the top of the file if the completion item will
+   * insert an unqualified type).
+   */
+  public void setAdditionalTextEdits(final List<TextEdit> additionalTextEdits) {
+    this.additionalTextEdits = additionalTextEdits;
+  }
+  
+  /**
+   * An optional set of characters that when pressed while this completion is active will accept it first and
+   * then type that character. <em>Note</em> that all commit characters should have {@code length=1} and that superfluous
+   * characters will be ignored.
+   */
+  @Pure
+  public List<String> getCommitCharacters() {
+    return this.commitCharacters;
+  }
+  
+  /**
+   * An optional set of characters that when pressed while this completion is active will accept it first and
+   * then type that character. <em>Note</em> that all commit characters should have {@code length=1} and that superfluous
+   * characters will be ignored.
+   */
+  public void setCommitCharacters(final List<String> commitCharacters) {
+    this.commitCharacters = commitCharacters;
+  }
+  
+  /**
+   * An optional command that is executed <em>after</em> inserting this completion. <em>Note</em> that
+   * additional modifications to the current document should be described with the
+   * {@link #additionalTextEdits} property.
+   */
+  @Pure
+  public Command getCommand() {
+    return this.command;
+  }
+  
+  /**
+   * An optional command that is executed <em>after</em> inserting this completion. <em>Note</em> that
+   * additional modifications to the current document should be described with the
+   * {@link #additionalTextEdits} property.
+   */
+  public void setCommand(final Command command) {
+    this.command = command;
+  }
+  
+  /**
+   * A data entry field that is preserved on a completion item between a completion and a completion resolve request.
+   */
+  @Pure
+  public Object getData() {
+    return this.data;
+  }
+  
+  /**
+   * A data entry field that is preserved on a completion item between a completion and a completion resolve request.
+   */
+  public void setData(final Object data) {
+    this.data = data;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("label", this.label);
+    b.add("kind", this.kind);
+    b.add("tags", this.tags);
+    b.add("detail", this.detail);
+    b.add("documentation", this.documentation);
+    b.add("deprecated", this.deprecated);
+    b.add("preselect", this.preselect);
+    b.add("sortText", this.sortText);
+    b.add("filterText", this.filterText);
+    b.add("insertText", this.insertText);
+    b.add("insertTextFormat", this.insertTextFormat);
+    b.add("insertTextMode", this.insertTextMode);
+    b.add("textEdit", this.textEdit);
+    b.add("additionalTextEdits", this.additionalTextEdits);
+    b.add("commitCharacters", this.commitCharacters);
+    b.add("command", this.command);
+    b.add("data", this.data);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CompletionItem other = (CompletionItem) obj;
+    if (this.label == null) {
+      if (other.label != null)
+        return false;
+    } else if (!this.label.equals(other.label))
+      return false;
+    if (this.kind == null) {
+      if (other.kind != null)
+        return false;
+    } else if (!this.kind.equals(other.kind))
+      return false;
+    if (this.tags == null) {
+      if (other.tags != null)
+        return false;
+    } else if (!this.tags.equals(other.tags))
+      return false;
+    if (this.detail == null) {
+      if (other.detail != null)
+        return false;
+    } else if (!this.detail.equals(other.detail))
+      return false;
+    if (this.documentation == null) {
+      if (other.documentation != null)
+        return false;
+    } else if (!this.documentation.equals(other.documentation))
+      return false;
+    if (this.deprecated == null) {
+      if (other.deprecated != null)
+        return false;
+    } else if (!this.deprecated.equals(other.deprecated))
+      return false;
+    if (this.preselect == null) {
+      if (other.preselect != null)
+        return false;
+    } else if (!this.preselect.equals(other.preselect))
+      return false;
+    if (this.sortText == null) {
+      if (other.sortText != null)
+        return false;
+    } else if (!this.sortText.equals(other.sortText))
+      return false;
+    if (this.filterText == null) {
+      if (other.filterText != null)
+        return false;
+    } else if (!this.filterText.equals(other.filterText))
+      return false;
+    if (this.insertText == null) {
+      if (other.insertText != null)
+        return false;
+    } else if (!this.insertText.equals(other.insertText))
+      return false;
+    if (this.insertTextFormat == null) {
+      if (other.insertTextFormat != null)
+        return false;
+    } else if (!this.insertTextFormat.equals(other.insertTextFormat))
+      return false;
+    if (this.insertTextMode == null) {
+      if (other.insertTextMode != null)
+        return false;
+    } else if (!this.insertTextMode.equals(other.insertTextMode))
+      return false;
+    if (this.textEdit == null) {
+      if (other.textEdit != null)
+        return false;
+    } else if (!this.textEdit.equals(other.textEdit))
+      return false;
+    if (this.additionalTextEdits == null) {
+      if (other.additionalTextEdits != null)
+        return false;
+    } else if (!this.additionalTextEdits.equals(other.additionalTextEdits))
+      return false;
+    if (this.commitCharacters == null) {
+      if (other.commitCharacters != null)
+        return false;
+    } else if (!this.commitCharacters.equals(other.commitCharacters))
+      return false;
+    if (this.command == null) {
+      if (other.command != null)
+        return false;
+    } else if (!this.command.equals(other.command))
+      return false;
+    if (this.data == null) {
+      if (other.data != null)
+        return false;
+    } else if (!this.data.equals(other.data))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.label== null) ? 0 : this.label.hashCode());
+    result = prime * result + ((this.kind== null) ? 0 : this.kind.hashCode());
+    result = prime * result + ((this.tags== null) ? 0 : this.tags.hashCode());
+    result = prime * result + ((this.detail== null) ? 0 : this.detail.hashCode());
+    result = prime * result + ((this.documentation== null) ? 0 : this.documentation.hashCode());
+    result = prime * result + ((this.deprecated== null) ? 0 : this.deprecated.hashCode());
+    result = prime * result + ((this.preselect== null) ? 0 : this.preselect.hashCode());
+    result = prime * result + ((this.sortText== null) ? 0 : this.sortText.hashCode());
+    result = prime * result + ((this.filterText== null) ? 0 : this.filterText.hashCode());
+    result = prime * result + ((this.insertText== null) ? 0 : this.insertText.hashCode());
+    result = prime * result + ((this.insertTextFormat== null) ? 0 : this.insertTextFormat.hashCode());
+    result = prime * result + ((this.insertTextMode== null) ? 0 : this.insertTextMode.hashCode());
+    result = prime * result + ((this.textEdit== null) ? 0 : this.textEdit.hashCode());
+    result = prime * result + ((this.additionalTextEdits== null) ? 0 : this.additionalTextEdits.hashCode());
+    result = prime * result + ((this.commitCharacters== null) ? 0 : this.commitCharacters.hashCode());
+    result = prime * result + ((this.command== null) ? 0 : this.command.hashCode());
+    return prime * result + ((this.data== null) ? 0 : this.data.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CompletionItemCapabilities.java b/java/org/eclipse/lsp4j/CompletionItemCapabilities.java
new file mode 100644
index 0000000..4dfe81b
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CompletionItemCapabilities.java
@@ -0,0 +1,368 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.CompletionItemInsertTextModeSupportCapabilities;
+import org.eclipse.lsp4j.CompletionItemResolveSupportCapabilities;
+import org.eclipse.lsp4j.CompletionItemTagSupportCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The client supports the following {@link CompletionItem} specific capabilities.
+ */
+@SuppressWarnings("all")
+public class CompletionItemCapabilities {
+  /**
+   * Client supports snippets as insert text.
+   * <p>
+   * A snippet can define tab stops and placeholders with `$1`, `$2`
+   * and `${3:foo}`. `$0` defines the final tab stop, it defaults to
+   * the end of the snippet. Placeholders with equal identifiers are linked,
+   * that is typing in one will update others too.
+   */
+  private Boolean snippetSupport;
+  
+  /**
+   * Client supports commit characters on a completion item.
+   */
+  private Boolean commitCharactersSupport;
+  
+  /**
+   * Client supports the following content formats for the documentation
+   * property. The order describes the preferred format of the client.
+   */
+  private List<String> documentationFormat;
+  
+  /**
+   * Client supports the deprecated property on a completion item.
+   */
+  private Boolean deprecatedSupport;
+  
+  /**
+   * Client supports the preselect property on a completion item.
+   */
+  private Boolean preselectSupport;
+  
+  /**
+   * Client supports the tag property on a completion item. Clients supporting
+   * tags have to handle unknown tags gracefully. Clients especially need to
+   * preserve unknown tags when sending a completion item back to the server in
+   * a resolve call.
+   * <p>
+   * Since 3.15.0
+   */
+  private CompletionItemTagSupportCapabilities tagSupport;
+  
+  /**
+   * Client support insert replace edit to control different behavior if a
+   * completion item is inserted in the text or should replace text.
+   * <p>
+   * Since 3.16.0
+   */
+  private Boolean insertReplaceSupport;
+  
+  /**
+   * Indicates which properties a client can resolve lazily on a completion
+   * item. Before version 3.16.0 only the predefined properties {@link CompletionItem#documentation}
+   * and {@link CompletionItem#detail} could be resolved lazily.
+   * <p>
+   * Since 3.16.0
+   */
+  private CompletionItemResolveSupportCapabilities resolveSupport;
+  
+  /**
+   * The client supports the {@link CompletionItem#insertTextMode} property on
+   * a completion item to override the whitespace handling mode
+   * as defined by the client.
+   * <p>
+   * Since 3.16.0
+   */
+  private CompletionItemInsertTextModeSupportCapabilities insertTextModeSupport;
+  
+  public CompletionItemCapabilities() {
+  }
+  
+  public CompletionItemCapabilities(final Boolean snippetSupport) {
+    this.snippetSupport = snippetSupport;
+  }
+  
+  /**
+   * Client supports snippets as insert text.
+   * <p>
+   * A snippet can define tab stops and placeholders with `$1`, `$2`
+   * and `${3:foo}`. `$0` defines the final tab stop, it defaults to
+   * the end of the snippet. Placeholders with equal identifiers are linked,
+   * that is typing in one will update others too.
+   */
+  @Pure
+  public Boolean getSnippetSupport() {
+    return this.snippetSupport;
+  }
+  
+  /**
+   * Client supports snippets as insert text.
+   * <p>
+   * A snippet can define tab stops and placeholders with `$1`, `$2`
+   * and `${3:foo}`. `$0` defines the final tab stop, it defaults to
+   * the end of the snippet. Placeholders with equal identifiers are linked,
+   * that is typing in one will update others too.
+   */
+  public void setSnippetSupport(final Boolean snippetSupport) {
+    this.snippetSupport = snippetSupport;
+  }
+  
+  /**
+   * Client supports commit characters on a completion item.
+   */
+  @Pure
+  public Boolean getCommitCharactersSupport() {
+    return this.commitCharactersSupport;
+  }
+  
+  /**
+   * Client supports commit characters on a completion item.
+   */
+  public void setCommitCharactersSupport(final Boolean commitCharactersSupport) {
+    this.commitCharactersSupport = commitCharactersSupport;
+  }
+  
+  /**
+   * Client supports the following content formats for the documentation
+   * property. The order describes the preferred format of the client.
+   */
+  @Pure
+  public List<String> getDocumentationFormat() {
+    return this.documentationFormat;
+  }
+  
+  /**
+   * Client supports the following content formats for the documentation
+   * property. The order describes the preferred format of the client.
+   */
+  public void setDocumentationFormat(final List<String> documentationFormat) {
+    this.documentationFormat = documentationFormat;
+  }
+  
+  /**
+   * Client supports the deprecated property on a completion item.
+   */
+  @Pure
+  public Boolean getDeprecatedSupport() {
+    return this.deprecatedSupport;
+  }
+  
+  /**
+   * Client supports the deprecated property on a completion item.
+   */
+  public void setDeprecatedSupport(final Boolean deprecatedSupport) {
+    this.deprecatedSupport = deprecatedSupport;
+  }
+  
+  /**
+   * Client supports the preselect property on a completion item.
+   */
+  @Pure
+  public Boolean getPreselectSupport() {
+    return this.preselectSupport;
+  }
+  
+  /**
+   * Client supports the preselect property on a completion item.
+   */
+  public void setPreselectSupport(final Boolean preselectSupport) {
+    this.preselectSupport = preselectSupport;
+  }
+  
+  /**
+   * Client supports the tag property on a completion item. Clients supporting
+   * tags have to handle unknown tags gracefully. Clients especially need to
+   * preserve unknown tags when sending a completion item back to the server in
+   * a resolve call.
+   * <p>
+   * Since 3.15.0
+   */
+  @Pure
+  public CompletionItemTagSupportCapabilities getTagSupport() {
+    return this.tagSupport;
+  }
+  
+  /**
+   * Client supports the tag property on a completion item. Clients supporting
+   * tags have to handle unknown tags gracefully. Clients especially need to
+   * preserve unknown tags when sending a completion item back to the server in
+   * a resolve call.
+   * <p>
+   * Since 3.15.0
+   */
+  public void setTagSupport(final CompletionItemTagSupportCapabilities tagSupport) {
+    this.tagSupport = tagSupport;
+  }
+  
+  /**
+   * Client support insert replace edit to control different behavior if a
+   * completion item is inserted in the text or should replace text.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public Boolean getInsertReplaceSupport() {
+    return this.insertReplaceSupport;
+  }
+  
+  /**
+   * Client support insert replace edit to control different behavior if a
+   * completion item is inserted in the text or should replace text.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setInsertReplaceSupport(final Boolean insertReplaceSupport) {
+    this.insertReplaceSupport = insertReplaceSupport;
+  }
+  
+  /**
+   * Indicates which properties a client can resolve lazily on a completion
+   * item. Before version 3.16.0 only the predefined properties {@link CompletionItem#documentation}
+   * and {@link CompletionItem#detail} could be resolved lazily.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public CompletionItemResolveSupportCapabilities getResolveSupport() {
+    return this.resolveSupport;
+  }
+  
+  /**
+   * Indicates which properties a client can resolve lazily on a completion
+   * item. Before version 3.16.0 only the predefined properties {@link CompletionItem#documentation}
+   * and {@link CompletionItem#detail} could be resolved lazily.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setResolveSupport(final CompletionItemResolveSupportCapabilities resolveSupport) {
+    this.resolveSupport = resolveSupport;
+  }
+  
+  /**
+   * The client supports the {@link CompletionItem#insertTextMode} property on
+   * a completion item to override the whitespace handling mode
+   * as defined by the client.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public CompletionItemInsertTextModeSupportCapabilities getInsertTextModeSupport() {
+    return this.insertTextModeSupport;
+  }
+  
+  /**
+   * The client supports the {@link CompletionItem#insertTextMode} property on
+   * a completion item to override the whitespace handling mode
+   * as defined by the client.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setInsertTextModeSupport(final CompletionItemInsertTextModeSupportCapabilities insertTextModeSupport) {
+    this.insertTextModeSupport = insertTextModeSupport;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("snippetSupport", this.snippetSupport);
+    b.add("commitCharactersSupport", this.commitCharactersSupport);
+    b.add("documentationFormat", this.documentationFormat);
+    b.add("deprecatedSupport", this.deprecatedSupport);
+    b.add("preselectSupport", this.preselectSupport);
+    b.add("tagSupport", this.tagSupport);
+    b.add("insertReplaceSupport", this.insertReplaceSupport);
+    b.add("resolveSupport", this.resolveSupport);
+    b.add("insertTextModeSupport", this.insertTextModeSupport);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CompletionItemCapabilities other = (CompletionItemCapabilities) obj;
+    if (this.snippetSupport == null) {
+      if (other.snippetSupport != null)
+        return false;
+    } else if (!this.snippetSupport.equals(other.snippetSupport))
+      return false;
+    if (this.commitCharactersSupport == null) {
+      if (other.commitCharactersSupport != null)
+        return false;
+    } else if (!this.commitCharactersSupport.equals(other.commitCharactersSupport))
+      return false;
+    if (this.documentationFormat == null) {
+      if (other.documentationFormat != null)
+        return false;
+    } else if (!this.documentationFormat.equals(other.documentationFormat))
+      return false;
+    if (this.deprecatedSupport == null) {
+      if (other.deprecatedSupport != null)
+        return false;
+    } else if (!this.deprecatedSupport.equals(other.deprecatedSupport))
+      return false;
+    if (this.preselectSupport == null) {
+      if (other.preselectSupport != null)
+        return false;
+    } else if (!this.preselectSupport.equals(other.preselectSupport))
+      return false;
+    if (this.tagSupport == null) {
+      if (other.tagSupport != null)
+        return false;
+    } else if (!this.tagSupport.equals(other.tagSupport))
+      return false;
+    if (this.insertReplaceSupport == null) {
+      if (other.insertReplaceSupport != null)
+        return false;
+    } else if (!this.insertReplaceSupport.equals(other.insertReplaceSupport))
+      return false;
+    if (this.resolveSupport == null) {
+      if (other.resolveSupport != null)
+        return false;
+    } else if (!this.resolveSupport.equals(other.resolveSupport))
+      return false;
+    if (this.insertTextModeSupport == null) {
+      if (other.insertTextModeSupport != null)
+        return false;
+    } else if (!this.insertTextModeSupport.equals(other.insertTextModeSupport))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.snippetSupport== null) ? 0 : this.snippetSupport.hashCode());
+    result = prime * result + ((this.commitCharactersSupport== null) ? 0 : this.commitCharactersSupport.hashCode());
+    result = prime * result + ((this.documentationFormat== null) ? 0 : this.documentationFormat.hashCode());
+    result = prime * result + ((this.deprecatedSupport== null) ? 0 : this.deprecatedSupport.hashCode());
+    result = prime * result + ((this.preselectSupport== null) ? 0 : this.preselectSupport.hashCode());
+    result = prime * result + ((this.tagSupport== null) ? 0 : this.tagSupport.hashCode());
+    result = prime * result + ((this.insertReplaceSupport== null) ? 0 : this.insertReplaceSupport.hashCode());
+    result = prime * result + ((this.resolveSupport== null) ? 0 : this.resolveSupport.hashCode());
+    return prime * result + ((this.insertTextModeSupport== null) ? 0 : this.insertTextModeSupport.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CompletionItemInsertTextModeSupportCapabilities.java b/java/org/eclipse/lsp4j/CompletionItemInsertTextModeSupportCapabilities.java
new file mode 100644
index 0000000..3596bb3
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CompletionItemInsertTextModeSupportCapabilities.java
@@ -0,0 +1,84 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.lsp4j.InsertTextMode;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The client supports the {@link CompletionItem#insertTextMode} property on
+ * a completion item to override the whitespace handling mode
+ * as defined by the client.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class CompletionItemInsertTextModeSupportCapabilities {
+  @NonNull
+  private List<InsertTextMode> valueSet;
+  
+  public CompletionItemInsertTextModeSupportCapabilities() {
+    ArrayList<InsertTextMode> _arrayList = new ArrayList<InsertTextMode>();
+    this.valueSet = _arrayList;
+  }
+  
+  public CompletionItemInsertTextModeSupportCapabilities(@NonNull final List<InsertTextMode> valueSet) {
+    this.valueSet = Preconditions.<List<InsertTextMode>>checkNotNull(valueSet, "valueSet");
+  }
+  
+  @Pure
+  @NonNull
+  public List<InsertTextMode> getValueSet() {
+    return this.valueSet;
+  }
+  
+  public void setValueSet(@NonNull final List<InsertTextMode> valueSet) {
+    this.valueSet = Preconditions.checkNotNull(valueSet, "valueSet");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("valueSet", this.valueSet);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CompletionItemInsertTextModeSupportCapabilities other = (CompletionItemInsertTextModeSupportCapabilities) obj;
+    if (this.valueSet == null) {
+      if (other.valueSet != null)
+        return false;
+    } else if (!this.valueSet.equals(other.valueSet))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.valueSet== null) ? 0 : this.valueSet.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CompletionItemKind.java b/java/org/eclipse/lsp4j/CompletionItemKind.java
new file mode 100644
index 0000000..2840f81
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CompletionItemKind.java
@@ -0,0 +1,86 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j;
+
+/**
+ * The kind of a completion entry.
+ */
+public enum CompletionItemKind {
+	
+	Text(1),
+	
+	Method(2),
+	
+	Function(3),
+	
+	Constructor(4),
+	
+	Field(5),
+	
+	Variable(6),
+	
+	Class(7),
+	
+	Interface(8),
+	
+	Module(9),
+	
+	Property(10),
+	
+	Unit(11),
+	
+	Value(12),
+	
+	Enum(13),
+	
+	Keyword(14),
+	
+	Snippet(15),
+	
+	Color(16),
+	
+	File(17),
+	
+	Reference(18),
+	
+	Folder(19),
+	
+	EnumMember(20),
+	
+	Constant(21),
+	
+	Struct(22),
+	
+	Event(23),
+	
+	Operator(24),
+	
+	TypeParameter(25);
+	
+	private final int value;
+	
+	CompletionItemKind(int value) {
+		this.value = value;
+	}
+	
+	public int getValue() {
+		return value;
+	}
+	
+	public static CompletionItemKind forValue(int value) {
+		CompletionItemKind[] allValues = CompletionItemKind.values();
+		if (value < 1 || value > allValues.length)
+			throw new IllegalArgumentException("Illegal enum value: " + value);
+		return allValues[value - 1];
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/CompletionItemKindCapabilities.java b/java/org/eclipse/lsp4j/CompletionItemKindCapabilities.java
new file mode 100644
index 0000000..e93bb9f
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CompletionItemKindCapabilities.java
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.CompletionItemKind;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The client supports the following {@link CompletionItemKind} specific
+ * capabilities.
+ */
+@SuppressWarnings("all")
+public class CompletionItemKindCapabilities {
+  /**
+   * The completion item kind values the client supports. When this
+   * property exists the client also guarantees that it will
+   * handle values outside its set gracefully and falls back
+   * to a default value when unknown.
+   * <p>
+   * If this property is not present the client only supports
+   * the completion items kinds from {@link CompletionItemKind#Text} to
+   * {@link CompletionItemKind#Reference} as defined in the initial version of the protocol.
+   */
+  private List<CompletionItemKind> valueSet;
+  
+  public CompletionItemKindCapabilities() {
+  }
+  
+  public CompletionItemKindCapabilities(final List<CompletionItemKind> valueSet) {
+    this.valueSet = valueSet;
+  }
+  
+  /**
+   * The completion item kind values the client supports. When this
+   * property exists the client also guarantees that it will
+   * handle values outside its set gracefully and falls back
+   * to a default value when unknown.
+   * <p>
+   * If this property is not present the client only supports
+   * the completion items kinds from {@link CompletionItemKind#Text} to
+   * {@link CompletionItemKind#Reference} as defined in the initial version of the protocol.
+   */
+  @Pure
+  public List<CompletionItemKind> getValueSet() {
+    return this.valueSet;
+  }
+  
+  /**
+   * The completion item kind values the client supports. When this
+   * property exists the client also guarantees that it will
+   * handle values outside its set gracefully and falls back
+   * to a default value when unknown.
+   * <p>
+   * If this property is not present the client only supports
+   * the completion items kinds from {@link CompletionItemKind#Text} to
+   * {@link CompletionItemKind#Reference} as defined in the initial version of the protocol.
+   */
+  public void setValueSet(final List<CompletionItemKind> valueSet) {
+    this.valueSet = valueSet;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("valueSet", this.valueSet);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CompletionItemKindCapabilities other = (CompletionItemKindCapabilities) obj;
+    if (this.valueSet == null) {
+      if (other.valueSet != null)
+        return false;
+    } else if (!this.valueSet.equals(other.valueSet))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.valueSet== null) ? 0 : this.valueSet.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CompletionItemResolveSupportCapabilities.java b/java/org/eclipse/lsp4j/CompletionItemResolveSupportCapabilities.java
new file mode 100644
index 0000000..e80ed7c
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CompletionItemResolveSupportCapabilities.java
@@ -0,0 +1,92 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Indicates which properties a client can resolve lazily on a completion
+ * item. Before version 3.16.0 only the predefined properties {@link CompletionItem#documentation}
+ * and {@link CompletionItem#detail} could be resolved lazily.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class CompletionItemResolveSupportCapabilities {
+  /**
+   * The properties that a client can resolve lazily.
+   */
+  @NonNull
+  private List<String> properties;
+  
+  public CompletionItemResolveSupportCapabilities() {
+    ArrayList<String> _arrayList = new ArrayList<String>();
+    this.properties = _arrayList;
+  }
+  
+  public CompletionItemResolveSupportCapabilities(@NonNull final List<String> properties) {
+    this.properties = Preconditions.<List<String>>checkNotNull(properties, "properties");
+  }
+  
+  /**
+   * The properties that a client can resolve lazily.
+   */
+  @Pure
+  @NonNull
+  public List<String> getProperties() {
+    return this.properties;
+  }
+  
+  /**
+   * The properties that a client can resolve lazily.
+   */
+  public void setProperties(@NonNull final List<String> properties) {
+    this.properties = Preconditions.checkNotNull(properties, "properties");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("properties", this.properties);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CompletionItemResolveSupportCapabilities other = (CompletionItemResolveSupportCapabilities) obj;
+    if (this.properties == null) {
+      if (other.properties != null)
+        return false;
+    } else if (!this.properties.equals(other.properties))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.properties== null) ? 0 : this.properties.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CompletionItemTag.java b/java/org/eclipse/lsp4j/CompletionItemTag.java
new file mode 100644
index 0000000..4ed1288
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CompletionItemTag.java
@@ -0,0 +1,44 @@
+/******************************************************************************
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+
+package org.eclipse.lsp4j;
+
+/**
+ * Completion item tags are extra annotations that tweak the rendering of a completion
+ * item.
+ * 
+ * Since 3.15.0
+ */
+public enum CompletionItemTag {
+
+    /**
+     * Render a completion as obsolete, usually using a strike-out.
+     */
+    Deprecated(1);
+
+    private final int value;
+
+    CompletionItemTag(int value) {
+        this.value = value;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public static CompletionItemTag forValue(int value) {
+        CompletionItemTag[] allValues = CompletionItemTag.values();
+        if (value < 1 || value > allValues.length)
+            throw new IllegalArgumentException("Illegal enum value: " + value);
+        return allValues[value - 1];
+    }
+}
\ No newline at end of file
diff --git a/java/org/eclipse/lsp4j/CompletionItemTagSupportCapabilities.java b/java/org/eclipse/lsp4j/CompletionItemTagSupportCapabilities.java
new file mode 100644
index 0000000..05f5294
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CompletionItemTagSupportCapabilities.java
@@ -0,0 +1,94 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.lsp4j.CompletionItemTag;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Client supports the tag property on a completion item. Clients supporting
+ * tags have to handle unknown tags gracefully. Clients especially need to
+ * preserve unknown tags when sending a completion item back to the server in
+ * a resolve call.
+ * <p>
+ * Since 3.15.0
+ */
+@SuppressWarnings("all")
+public class CompletionItemTagSupportCapabilities {
+  /**
+   * The tags supported by the client.
+   */
+  @NonNull
+  private List<CompletionItemTag> valueSet;
+  
+  public CompletionItemTagSupportCapabilities() {
+    ArrayList<CompletionItemTag> _arrayList = new ArrayList<CompletionItemTag>();
+    this.valueSet = _arrayList;
+  }
+  
+  public CompletionItemTagSupportCapabilities(@NonNull final List<CompletionItemTag> valueSet) {
+    this.valueSet = Preconditions.<List<CompletionItemTag>>checkNotNull(valueSet, "valueSet");
+  }
+  
+  /**
+   * The tags supported by the client.
+   */
+  @Pure
+  @NonNull
+  public List<CompletionItemTag> getValueSet() {
+    return this.valueSet;
+  }
+  
+  /**
+   * The tags supported by the client.
+   */
+  public void setValueSet(@NonNull final List<CompletionItemTag> valueSet) {
+    this.valueSet = Preconditions.checkNotNull(valueSet, "valueSet");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("valueSet", this.valueSet);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CompletionItemTagSupportCapabilities other = (CompletionItemTagSupportCapabilities) obj;
+    if (this.valueSet == null) {
+      if (other.valueSet != null)
+        return false;
+    } else if (!this.valueSet.equals(other.valueSet))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.valueSet== null) ? 0 : this.valueSet.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CompletionList.java b/java/org/eclipse/lsp4j/CompletionList.java
new file mode 100644
index 0000000..249a348
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CompletionList.java
@@ -0,0 +1,119 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.lsp4j.CompletionItem;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Represents a collection of completion items to be presented in the editor.
+ */
+@SuppressWarnings("all")
+public class CompletionList {
+  /**
+   * This list it not complete. Further typing should result in recomputing this list.
+   */
+  private boolean isIncomplete;
+  
+  /**
+   * The completion items.
+   */
+  @NonNull
+  private List<CompletionItem> items;
+  
+  public CompletionList() {
+    this(new ArrayList<CompletionItem>());
+  }
+  
+  public CompletionList(@NonNull final List<CompletionItem> items) {
+    this.items = Preconditions.<List<CompletionItem>>checkNotNull(items, "items");
+  }
+  
+  public CompletionList(final boolean isIncomplete, @NonNull final List<CompletionItem> items) {
+    this(items);
+    this.isIncomplete = isIncomplete;
+  }
+  
+  /**
+   * This list it not complete. Further typing should result in recomputing this list.
+   */
+  @Pure
+  public boolean isIncomplete() {
+    return this.isIncomplete;
+  }
+  
+  /**
+   * This list it not complete. Further typing should result in recomputing this list.
+   */
+  public void setIsIncomplete(final boolean isIncomplete) {
+    this.isIncomplete = isIncomplete;
+  }
+  
+  /**
+   * The completion items.
+   */
+  @Pure
+  @NonNull
+  public List<CompletionItem> getItems() {
+    return this.items;
+  }
+  
+  /**
+   * The completion items.
+   */
+  public void setItems(@NonNull final List<CompletionItem> items) {
+    this.items = Preconditions.checkNotNull(items, "items");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("isIncomplete", this.isIncomplete);
+    b.add("items", this.items);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CompletionList other = (CompletionList) obj;
+    if (other.isIncomplete != this.isIncomplete)
+      return false;
+    if (this.items == null) {
+      if (other.items != null)
+        return false;
+    } else if (!this.items.equals(other.items))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + (this.isIncomplete ? 1231 : 1237);
+    return prime * result + ((this.items== null) ? 0 : this.items.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CompletionOptions.java b/java/org/eclipse/lsp4j/CompletionOptions.java
new file mode 100644
index 0000000..c678a6b
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CompletionOptions.java
@@ -0,0 +1,166 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.AbstractWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Completion options.
+ */
+@SuppressWarnings("all")
+public class CompletionOptions extends AbstractWorkDoneProgressOptions {
+  /**
+   * The server provides support to resolve additional information for a completion item.
+   */
+  private Boolean resolveProvider;
+  
+  /**
+   * The characters that trigger completion automatically.
+   */
+  private List<String> triggerCharacters;
+  
+  /**
+   * The list of all possible characters that commit a completion. This field
+   * can be used if clients don't support individual commit characters per
+   * completion item. See client capability
+   * {@link CompletionItemCapabilities#commitCharactersSupport}.
+   * <p>
+   * If a server provides both {@code allCommitCharacters} and commit characters on
+   * an individual completion item the ones on the completion item win.
+   * <p>
+   * Since 3.2.0
+   */
+  private List<String> allCommitCharacters;
+  
+  public CompletionOptions() {
+  }
+  
+  public CompletionOptions(final Boolean resolveProvider, final List<String> triggerCharacters) {
+    this.resolveProvider = resolveProvider;
+    this.triggerCharacters = triggerCharacters;
+  }
+  
+  /**
+   * The server provides support to resolve additional information for a completion item.
+   */
+  @Pure
+  public Boolean getResolveProvider() {
+    return this.resolveProvider;
+  }
+  
+  /**
+   * The server provides support to resolve additional information for a completion item.
+   */
+  public void setResolveProvider(final Boolean resolveProvider) {
+    this.resolveProvider = resolveProvider;
+  }
+  
+  /**
+   * The characters that trigger completion automatically.
+   */
+  @Pure
+  public List<String> getTriggerCharacters() {
+    return this.triggerCharacters;
+  }
+  
+  /**
+   * The characters that trigger completion automatically.
+   */
+  public void setTriggerCharacters(final List<String> triggerCharacters) {
+    this.triggerCharacters = triggerCharacters;
+  }
+  
+  /**
+   * The list of all possible characters that commit a completion. This field
+   * can be used if clients don't support individual commit characters per
+   * completion item. See client capability
+   * {@link CompletionItemCapabilities#commitCharactersSupport}.
+   * <p>
+   * If a server provides both {@code allCommitCharacters} and commit characters on
+   * an individual completion item the ones on the completion item win.
+   * <p>
+   * Since 3.2.0
+   */
+  @Pure
+  public List<String> getAllCommitCharacters() {
+    return this.allCommitCharacters;
+  }
+  
+  /**
+   * The list of all possible characters that commit a completion. This field
+   * can be used if clients don't support individual commit characters per
+   * completion item. See client capability
+   * {@link CompletionItemCapabilities#commitCharactersSupport}.
+   * <p>
+   * If a server provides both {@code allCommitCharacters} and commit characters on
+   * an individual completion item the ones on the completion item win.
+   * <p>
+   * Since 3.2.0
+   */
+  public void setAllCommitCharacters(final List<String> allCommitCharacters) {
+    this.allCommitCharacters = allCommitCharacters;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("resolveProvider", this.resolveProvider);
+    b.add("triggerCharacters", this.triggerCharacters);
+    b.add("allCommitCharacters", this.allCommitCharacters);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    CompletionOptions other = (CompletionOptions) obj;
+    if (this.resolveProvider == null) {
+      if (other.resolveProvider != null)
+        return false;
+    } else if (!this.resolveProvider.equals(other.resolveProvider))
+      return false;
+    if (this.triggerCharacters == null) {
+      if (other.triggerCharacters != null)
+        return false;
+    } else if (!this.triggerCharacters.equals(other.triggerCharacters))
+      return false;
+    if (this.allCommitCharacters == null) {
+      if (other.allCommitCharacters != null)
+        return false;
+    } else if (!this.allCommitCharacters.equals(other.allCommitCharacters))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.resolveProvider== null) ? 0 : this.resolveProvider.hashCode());
+    result = prime * result + ((this.triggerCharacters== null) ? 0 : this.triggerCharacters.hashCode());
+    return prime * result + ((this.allCommitCharacters== null) ? 0 : this.allCommitCharacters.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CompletionParams.java b/java/org/eclipse/lsp4j/CompletionParams.java
new file mode 100644
index 0000000..700ba55
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CompletionParams.java
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.CompletionContext;
+import org.eclipse.lsp4j.Position;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.TextDocumentPositionAndWorkDoneProgressAndPartialResultParams;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The Completion request is sent from the client to the server to compute completion items at a given cursor position.
+ */
+@SuppressWarnings("all")
+public class CompletionParams extends TextDocumentPositionAndWorkDoneProgressAndPartialResultParams {
+  /**
+   * The completion context. This is only available if the client specifies
+   * to send this using {@link CompletionCapabilities#contextSupport} as true.
+   */
+  private CompletionContext context;
+  
+  public CompletionParams() {
+  }
+  
+  public CompletionParams(@NonNull final TextDocumentIdentifier textDocument, @NonNull final Position position) {
+    super(textDocument, position);
+  }
+  
+  public CompletionParams(@NonNull final TextDocumentIdentifier textDocument, @NonNull final Position position, final CompletionContext context) {
+    this(textDocument, position);
+    this.context = context;
+  }
+  
+  /**
+   * The completion context. This is only available if the client specifies
+   * to send this using {@link CompletionCapabilities#contextSupport} as true.
+   */
+  @Pure
+  public CompletionContext getContext() {
+    return this.context;
+  }
+  
+  /**
+   * The completion context. This is only available if the client specifies
+   * to send this using {@link CompletionCapabilities#contextSupport} as true.
+   */
+  public void setContext(final CompletionContext context) {
+    this.context = context;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("context", this.context);
+    b.add("partialResultToken", getPartialResultToken());
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("textDocument", getTextDocument());
+    b.add("uri", getUri());
+    b.add("position", getPosition());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    CompletionParams other = (CompletionParams) obj;
+    if (this.context == null) {
+      if (other.context != null)
+        return false;
+    } else if (!this.context.equals(other.context))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.context== null) ? 0 : this.context.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CompletionRegistrationOptions.java b/java/org/eclipse/lsp4j/CompletionRegistrationOptions.java
new file mode 100644
index 0000000..70edeca
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CompletionRegistrationOptions.java
@@ -0,0 +1,185 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.AbstractTextDocumentRegistrationAndWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class CompletionRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+  /**
+   * Most tools trigger completion request automatically without explicitly requesting
+   * it using a keyboard shortcut (e.g. Ctrl+Space). Typically they do so when the user
+   * starts to type an identifier. For example if the user types `c` in a JavaScript file
+   * code complete will automatically pop up present `console` besides others as a
+   * completion item. Characters that make up identifiers don't need to be listed here.
+   * <p>
+   * If code complete should automatically be trigger on characters not being valid inside
+   * an identifier (for example `.` in JavaScript) list them in `triggerCharacters`.
+   */
+  private List<String> triggerCharacters;
+  
+  /**
+   * The server provides support to resolve additional information for a completion item.
+   */
+  private Boolean resolveProvider;
+  
+  /**
+   * The list of all possible characters that commit a completion. This field
+   * can be used if clients don't support individual commit characters per
+   * completion item. See client capability
+   * {@link CompletionItemCapabilities#commitCharactersSupport}.
+   * <p>
+   * If a server provides both {@code allCommitCharacters} and commit characters on
+   * an individual completion item the ones on the completion item win.
+   * <p>
+   * Since 3.2.0
+   */
+  private List<String> allCommitCharacters;
+  
+  public CompletionRegistrationOptions() {
+  }
+  
+  public CompletionRegistrationOptions(final List<String> triggerCharacters, final Boolean resolveProvider) {
+    this.triggerCharacters = triggerCharacters;
+    this.resolveProvider = resolveProvider;
+  }
+  
+  /**
+   * Most tools trigger completion request automatically without explicitly requesting
+   * it using a keyboard shortcut (e.g. Ctrl+Space). Typically they do so when the user
+   * starts to type an identifier. For example if the user types `c` in a JavaScript file
+   * code complete will automatically pop up present `console` besides others as a
+   * completion item. Characters that make up identifiers don't need to be listed here.
+   * <p>
+   * If code complete should automatically be trigger on characters not being valid inside
+   * an identifier (for example `.` in JavaScript) list them in `triggerCharacters`.
+   */
+  @Pure
+  public List<String> getTriggerCharacters() {
+    return this.triggerCharacters;
+  }
+  
+  /**
+   * Most tools trigger completion request automatically without explicitly requesting
+   * it using a keyboard shortcut (e.g. Ctrl+Space). Typically they do so when the user
+   * starts to type an identifier. For example if the user types `c` in a JavaScript file
+   * code complete will automatically pop up present `console` besides others as a
+   * completion item. Characters that make up identifiers don't need to be listed here.
+   * <p>
+   * If code complete should automatically be trigger on characters not being valid inside
+   * an identifier (for example `.` in JavaScript) list them in `triggerCharacters`.
+   */
+  public void setTriggerCharacters(final List<String> triggerCharacters) {
+    this.triggerCharacters = triggerCharacters;
+  }
+  
+  /**
+   * The server provides support to resolve additional information for a completion item.
+   */
+  @Pure
+  public Boolean getResolveProvider() {
+    return this.resolveProvider;
+  }
+  
+  /**
+   * The server provides support to resolve additional information for a completion item.
+   */
+  public void setResolveProvider(final Boolean resolveProvider) {
+    this.resolveProvider = resolveProvider;
+  }
+  
+  /**
+   * The list of all possible characters that commit a completion. This field
+   * can be used if clients don't support individual commit characters per
+   * completion item. See client capability
+   * {@link CompletionItemCapabilities#commitCharactersSupport}.
+   * <p>
+   * If a server provides both {@code allCommitCharacters} and commit characters on
+   * an individual completion item the ones on the completion item win.
+   * <p>
+   * Since 3.2.0
+   */
+  @Pure
+  public List<String> getAllCommitCharacters() {
+    return this.allCommitCharacters;
+  }
+  
+  /**
+   * The list of all possible characters that commit a completion. This field
+   * can be used if clients don't support individual commit characters per
+   * completion item. See client capability
+   * {@link CompletionItemCapabilities#commitCharactersSupport}.
+   * <p>
+   * If a server provides both {@code allCommitCharacters} and commit characters on
+   * an individual completion item the ones on the completion item win.
+   * <p>
+   * Since 3.2.0
+   */
+  public void setAllCommitCharacters(final List<String> allCommitCharacters) {
+    this.allCommitCharacters = allCommitCharacters;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("triggerCharacters", this.triggerCharacters);
+    b.add("resolveProvider", this.resolveProvider);
+    b.add("allCommitCharacters", this.allCommitCharacters);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    CompletionRegistrationOptions other = (CompletionRegistrationOptions) obj;
+    if (this.triggerCharacters == null) {
+      if (other.triggerCharacters != null)
+        return false;
+    } else if (!this.triggerCharacters.equals(other.triggerCharacters))
+      return false;
+    if (this.resolveProvider == null) {
+      if (other.resolveProvider != null)
+        return false;
+    } else if (!this.resolveProvider.equals(other.resolveProvider))
+      return false;
+    if (this.allCommitCharacters == null) {
+      if (other.allCommitCharacters != null)
+        return false;
+    } else if (!this.allCommitCharacters.equals(other.allCommitCharacters))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.triggerCharacters== null) ? 0 : this.triggerCharacters.hashCode());
+    result = prime * result + ((this.resolveProvider== null) ? 0 : this.resolveProvider.hashCode());
+    return prime * result + ((this.allCommitCharacters== null) ? 0 : this.allCommitCharacters.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CompletionTriggerKind.java b/java/org/eclipse/lsp4j/CompletionTriggerKind.java
new file mode 100644
index 0000000..02bb99d
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CompletionTriggerKind.java
@@ -0,0 +1,53 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j;
+
+/**
+ * How a completion was triggered
+ */
+public enum CompletionTriggerKind {
+	
+	/**
+	 * Completion was triggered by typing an identifier (24x7 code
+	 * complete), manual invocation (e.g Ctrl+Space) or via API.
+	 */
+	Invoked(1),
+	
+	/**
+	 * Completion was triggered by a trigger character specified by
+	 * the `triggerCharacters` properties of the `CompletionRegistrationOptions`.
+	 */
+	TriggerCharacter(2),
+	
+	/**
+	 * Completion was re-triggered as the current completion list is incomplete.
+	 */
+	TriggerForIncompleteCompletions(3);
+	
+	private final int value;
+	
+	CompletionTriggerKind(int value) {
+		this.value = value;
+	}
+	
+	public int getValue() {
+		return value;
+	}
+	
+	public static CompletionTriggerKind forValue(int value) {
+		CompletionTriggerKind[] allValues = CompletionTriggerKind.values();
+		if (value < 1 || value > allValues.length)
+			throw new IllegalArgumentException("Illegal enum value: " + value);
+		return allValues[value - 1];
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/ConfigurationItem.java b/java/org/eclipse/lsp4j/ConfigurationItem.java
new file mode 100644
index 0000000..14b8c6f
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ConfigurationItem.java
@@ -0,0 +1,112 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A ConfigurationItem consist of the configuration section to ask for and an additional scope URI.
+ * The configuration section asked for is defined by the server and doesn’t necessarily need to
+ * correspond to the configuration store used by the client. So a server might ask for a configuration
+ * {@code cpp.formatterOptions} but the client stores the configuration in an XML store layout differently.
+ * It is up to the client to do the necessary conversion. If a scope URI is provided the client
+ * should return the setting scoped to the provided resource. If the client for example uses
+ * EditorConfig to manage its settings the configuration should be returned for the passed resource
+ * URI. If the client can't provide a configuration setting for a given scope then null needs to be
+ * present in the returned array.
+ * <p>
+ * Since 3.6.0
+ */
+@SuppressWarnings("all")
+public class ConfigurationItem {
+  /**
+   * The scope to get the configuration section for.
+   */
+  private String scopeUri;
+  
+  /**
+   * The configuration section asked for.
+   */
+  private String section;
+  
+  /**
+   * The scope to get the configuration section for.
+   */
+  @Pure
+  public String getScopeUri() {
+    return this.scopeUri;
+  }
+  
+  /**
+   * The scope to get the configuration section for.
+   */
+  public void setScopeUri(final String scopeUri) {
+    this.scopeUri = scopeUri;
+  }
+  
+  /**
+   * The configuration section asked for.
+   */
+  @Pure
+  public String getSection() {
+    return this.section;
+  }
+  
+  /**
+   * The configuration section asked for.
+   */
+  public void setSection(final String section) {
+    this.section = section;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("scopeUri", this.scopeUri);
+    b.add("section", this.section);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ConfigurationItem other = (ConfigurationItem) obj;
+    if (this.scopeUri == null) {
+      if (other.scopeUri != null)
+        return false;
+    } else if (!this.scopeUri.equals(other.scopeUri))
+      return false;
+    if (this.section == null) {
+      if (other.section != null)
+        return false;
+    } else if (!this.section.equals(other.section))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.scopeUri== null) ? 0 : this.scopeUri.hashCode());
+    return prime * result + ((this.section== null) ? 0 : this.section.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ConfigurationParams.java b/java/org/eclipse/lsp4j/ConfigurationParams.java
new file mode 100644
index 0000000..e4fc656
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ConfigurationParams.java
@@ -0,0 +1,83 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.ConfigurationItem;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The workspace/configuration request is sent from the server to the client to fetch configuration
+ * settings from the client. The request can fetch several configuration settings in one roundtrip.
+ * The order of the returned configuration settings correspond to the order of the passed
+ * {@link ConfigurationItem}s (e.g. the first item in the response is the result for the first
+ * configuration item in the params).
+ * <p>
+ * Since 3.6.0
+ */
+@SuppressWarnings("all")
+public class ConfigurationParams {
+  @NonNull
+  private List<ConfigurationItem> items;
+  
+  public ConfigurationParams() {
+  }
+  
+  public ConfigurationParams(@NonNull final List<ConfigurationItem> items) {
+    this.items = Preconditions.<List<ConfigurationItem>>checkNotNull(items, "items");
+  }
+  
+  @Pure
+  @NonNull
+  public List<ConfigurationItem> getItems() {
+    return this.items;
+  }
+  
+  public void setItems(@NonNull final List<ConfigurationItem> items) {
+    this.items = Preconditions.checkNotNull(items, "items");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("items", this.items);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ConfigurationParams other = (ConfigurationParams) obj;
+    if (this.items == null) {
+      if (other.items != null)
+        return false;
+    } else if (!this.items.equals(other.items))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.items== null) ? 0 : this.items.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CreateFile.java b/java/org/eclipse/lsp4j/CreateFile.java
new file mode 100644
index 0000000..7494ee5
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CreateFile.java
@@ -0,0 +1,127 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.CreateFileOptions;
+import org.eclipse.lsp4j.ResourceOperation;
+import org.eclipse.lsp4j.ResourceOperationKind;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Create file operation
+ */
+@SuppressWarnings("all")
+public class CreateFile extends ResourceOperation {
+  /**
+   * The resource to create.
+   */
+  @NonNull
+  private String uri;
+  
+  /**
+   * Additional options
+   */
+  private CreateFileOptions options;
+  
+  public CreateFile() {
+    super(ResourceOperationKind.Create);
+  }
+  
+  public CreateFile(@NonNull final String uri) {
+    super(ResourceOperationKind.Create);
+    this.uri = Preconditions.<String>checkNotNull(uri, "uri");
+  }
+  
+  public CreateFile(@NonNull final String uri, final CreateFileOptions options) {
+    this(uri);
+    this.options = options;
+  }
+  
+  /**
+   * The resource to create.
+   */
+  @Pure
+  @NonNull
+  public String getUri() {
+    return this.uri;
+  }
+  
+  /**
+   * The resource to create.
+   */
+  public void setUri(@NonNull final String uri) {
+    this.uri = Preconditions.checkNotNull(uri, "uri");
+  }
+  
+  /**
+   * Additional options
+   */
+  @Pure
+  public CreateFileOptions getOptions() {
+    return this.options;
+  }
+  
+  /**
+   * Additional options
+   */
+  public void setOptions(final CreateFileOptions options) {
+    this.options = options;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("uri", this.uri);
+    b.add("options", this.options);
+    b.add("kind", getKind());
+    b.add("annotationId", getAnnotationId());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    CreateFile other = (CreateFile) obj;
+    if (this.uri == null) {
+      if (other.uri != null)
+        return false;
+    } else if (!this.uri.equals(other.uri))
+      return false;
+    if (this.options == null) {
+      if (other.options != null)
+        return false;
+    } else if (!this.options.equals(other.options))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.uri== null) ? 0 : this.uri.hashCode());
+    return prime * result + ((this.options== null) ? 0 : this.options.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CreateFileOptions.java b/java/org/eclipse/lsp4j/CreateFileOptions.java
new file mode 100644
index 0000000..5deb7ee
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CreateFileOptions.java
@@ -0,0 +1,110 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Options to create a file.
+ */
+@SuppressWarnings("all")
+public class CreateFileOptions {
+  /**
+   * Overwrite existing file. Overwrite wins over {@link #ignoreIfExists}
+   */
+  private Boolean overwrite;
+  
+  /**
+   * Ignore if exists.
+   */
+  private Boolean ignoreIfExists;
+  
+  public CreateFileOptions() {
+  }
+  
+  public CreateFileOptions(final Boolean overwrite, final Boolean ignoreIfExists) {
+    this.overwrite = overwrite;
+    this.ignoreIfExists = ignoreIfExists;
+  }
+  
+  /**
+   * Overwrite existing file. Overwrite wins over {@link #ignoreIfExists}
+   */
+  @Pure
+  public Boolean getOverwrite() {
+    return this.overwrite;
+  }
+  
+  /**
+   * Overwrite existing file. Overwrite wins over {@link #ignoreIfExists}
+   */
+  public void setOverwrite(final Boolean overwrite) {
+    this.overwrite = overwrite;
+  }
+  
+  /**
+   * Ignore if exists.
+   */
+  @Pure
+  public Boolean getIgnoreIfExists() {
+    return this.ignoreIfExists;
+  }
+  
+  /**
+   * Ignore if exists.
+   */
+  public void setIgnoreIfExists(final Boolean ignoreIfExists) {
+    this.ignoreIfExists = ignoreIfExists;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("overwrite", this.overwrite);
+    b.add("ignoreIfExists", this.ignoreIfExists);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CreateFileOptions other = (CreateFileOptions) obj;
+    if (this.overwrite == null) {
+      if (other.overwrite != null)
+        return false;
+    } else if (!this.overwrite.equals(other.overwrite))
+      return false;
+    if (this.ignoreIfExists == null) {
+      if (other.ignoreIfExists != null)
+        return false;
+    } else if (!this.ignoreIfExists.equals(other.ignoreIfExists))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.overwrite== null) ? 0 : this.overwrite.hashCode());
+    return prime * result + ((this.ignoreIfExists== null) ? 0 : this.ignoreIfExists.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/CreateFilesParams.java b/java/org/eclipse/lsp4j/CreateFilesParams.java
new file mode 100644
index 0000000..cba17ab
--- /dev/null
+++ b/java/org/eclipse/lsp4j/CreateFilesParams.java
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.lsp4j.FileCreate;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The parameters sent in notifications/requests for user-initiated creation
+ * of files.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class CreateFilesParams {
+  /**
+   * An array of all files/folders created in this operation.
+   */
+  @NonNull
+  private List<FileCreate> files = new ArrayList<FileCreate>();
+  
+  public CreateFilesParams() {
+  }
+  
+  public CreateFilesParams(@NonNull final List<FileCreate> files) {
+    this.files = Preconditions.<List<FileCreate>>checkNotNull(files, "files");
+  }
+  
+  /**
+   * An array of all files/folders created in this operation.
+   */
+  @Pure
+  @NonNull
+  public List<FileCreate> getFiles() {
+    return this.files;
+  }
+  
+  /**
+   * An array of all files/folders created in this operation.
+   */
+  public void setFiles(@NonNull final List<FileCreate> files) {
+    this.files = Preconditions.checkNotNull(files, "files");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("files", this.files);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CreateFilesParams other = (CreateFilesParams) obj;
+    if (this.files == null) {
+      if (other.files != null)
+        return false;
+    } else if (!this.files.equals(other.files))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.files== null) ? 0 : this.files.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DeclarationCapabilities.java b/java/org/eclipse/lsp4j/DeclarationCapabilities.java
new file mode 100644
index 0000000..13c9184
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DeclarationCapabilities.java
@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the `textDocument/declaration`
+ * <p>
+ * Since 3.14.0
+ */
+@SuppressWarnings("all")
+public class DeclarationCapabilities extends DynamicRegistrationCapabilities {
+  /**
+   * The client supports additional metadata in the form of declaration links.
+   */
+  private Boolean linkSupport;
+  
+  public DeclarationCapabilities() {
+  }
+  
+  public DeclarationCapabilities(final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+  }
+  
+  public DeclarationCapabilities(final Boolean dynamicRegistration, final Boolean linkSupport) {
+    super(dynamicRegistration);
+    this.linkSupport = linkSupport;
+  }
+  
+  /**
+   * The client supports additional metadata in the form of declaration links.
+   */
+  @Pure
+  public Boolean getLinkSupport() {
+    return this.linkSupport;
+  }
+  
+  /**
+   * The client supports additional metadata in the form of declaration links.
+   */
+  public void setLinkSupport(final Boolean linkSupport) {
+    this.linkSupport = linkSupport;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("linkSupport", this.linkSupport);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    DeclarationCapabilities other = (DeclarationCapabilities) obj;
+    if (this.linkSupport == null) {
+      if (other.linkSupport != null)
+        return false;
+    } else if (!this.linkSupport.equals(other.linkSupport))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.linkSupport== null) ? 0 : this.linkSupport.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DeclarationOptions.java b/java/org/eclipse/lsp4j/DeclarationOptions.java
new file mode 100644
index 0000000..a2dddfa
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DeclarationOptions.java
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class DeclarationOptions extends AbstractWorkDoneProgressOptions {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DeclarationParams.java b/java/org/eclipse/lsp4j/DeclarationParams.java
new file mode 100644
index 0000000..e64c062
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DeclarationParams.java
@@ -0,0 +1,65 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.Position;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.TextDocumentPositionAndWorkDoneProgressAndPartialResultParams;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The go to declaration request is sent from the client to the server to resolve the declaration
+ * location of a symbol at a given text document position.
+ */
+@SuppressWarnings("all")
+public class DeclarationParams extends TextDocumentPositionAndWorkDoneProgressAndPartialResultParams {
+  public DeclarationParams() {
+  }
+  
+  public DeclarationParams(@NonNull final TextDocumentIdentifier textDocument, @NonNull final Position position) {
+    super(textDocument, position);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("partialResultToken", getPartialResultToken());
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("textDocument", getTextDocument());
+    b.add("uri", getUri());
+    b.add("position", getPosition());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DeclarationRegistrationOptions.java b/java/org/eclipse/lsp4j/DeclarationRegistrationOptions.java
new file mode 100644
index 0000000..7445755
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DeclarationRegistrationOptions.java
@@ -0,0 +1,85 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractTextDocumentRegistrationAndWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class DeclarationRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  private String id;
+  
+  public DeclarationRegistrationOptions() {
+  }
+  
+  public DeclarationRegistrationOptions(final String id) {
+    this.id = id;
+  }
+  
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  @Pure
+  public String getId() {
+    return this.id;
+  }
+  
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  public void setId(final String id) {
+    this.id = id;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("id", this.id);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    DeclarationRegistrationOptions other = (DeclarationRegistrationOptions) obj;
+    if (this.id == null) {
+      if (other.id != null)
+        return false;
+    } else if (!this.id.equals(other.id))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.id== null) ? 0 : this.id.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DefinitionCapabilities.java b/java/org/eclipse/lsp4j/DefinitionCapabilities.java
new file mode 100644
index 0000000..c2099a5
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DefinitionCapabilities.java
@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the `textDocument/definition`
+ * <p>
+ * Since 3.14.0
+ */
+@SuppressWarnings("all")
+public class DefinitionCapabilities extends DynamicRegistrationCapabilities {
+  /**
+   * The client supports additional metadata in the form of definition links.
+   */
+  private Boolean linkSupport;
+  
+  public DefinitionCapabilities() {
+  }
+  
+  public DefinitionCapabilities(final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+  }
+  
+  public DefinitionCapabilities(final Boolean dynamicRegistration, final Boolean linkSupport) {
+    super(dynamicRegistration);
+    this.linkSupport = linkSupport;
+  }
+  
+  /**
+   * The client supports additional metadata in the form of definition links.
+   */
+  @Pure
+  public Boolean getLinkSupport() {
+    return this.linkSupport;
+  }
+  
+  /**
+   * The client supports additional metadata in the form of definition links.
+   */
+  public void setLinkSupport(final Boolean linkSupport) {
+    this.linkSupport = linkSupport;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("linkSupport", this.linkSupport);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    DefinitionCapabilities other = (DefinitionCapabilities) obj;
+    if (this.linkSupport == null) {
+      if (other.linkSupport != null)
+        return false;
+    } else if (!this.linkSupport.equals(other.linkSupport))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.linkSupport== null) ? 0 : this.linkSupport.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DefinitionOptions.java b/java/org/eclipse/lsp4j/DefinitionOptions.java
new file mode 100644
index 0000000..7e77640
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DefinitionOptions.java
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class DefinitionOptions extends AbstractWorkDoneProgressOptions {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DefinitionParams.java b/java/org/eclipse/lsp4j/DefinitionParams.java
new file mode 100644
index 0000000..d289a9f
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DefinitionParams.java
@@ -0,0 +1,65 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.Position;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.TextDocumentPositionAndWorkDoneProgressAndPartialResultParams;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The go to definition request is sent from the client to the server to resolve the definition
+ * location of a symbol at a given text document position.
+ */
+@SuppressWarnings("all")
+public class DefinitionParams extends TextDocumentPositionAndWorkDoneProgressAndPartialResultParams {
+  public DefinitionParams() {
+  }
+  
+  public DefinitionParams(@NonNull final TextDocumentIdentifier textDocument, @NonNull final Position position) {
+    super(textDocument, position);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("partialResultToken", getPartialResultToken());
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("textDocument", getTextDocument());
+    b.add("uri", getUri());
+    b.add("position", getPosition());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DefinitionRegistrationOptions.java b/java/org/eclipse/lsp4j/DefinitionRegistrationOptions.java
new file mode 100644
index 0000000..c480a26
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DefinitionRegistrationOptions.java
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractTextDocumentRegistrationAndWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class DefinitionRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DeleteFile.java b/java/org/eclipse/lsp4j/DeleteFile.java
new file mode 100644
index 0000000..904a317
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DeleteFile.java
@@ -0,0 +1,127 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DeleteFileOptions;
+import org.eclipse.lsp4j.ResourceOperation;
+import org.eclipse.lsp4j.ResourceOperationKind;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Delete file operation
+ */
+@SuppressWarnings("all")
+public class DeleteFile extends ResourceOperation {
+  /**
+   * The file to delete.
+   */
+  @NonNull
+  private String uri;
+  
+  /**
+   * Delete options.
+   */
+  private DeleteFileOptions options;
+  
+  public DeleteFile() {
+    super(ResourceOperationKind.Delete);
+  }
+  
+  public DeleteFile(@NonNull final String uri) {
+    super(ResourceOperationKind.Delete);
+    this.uri = Preconditions.<String>checkNotNull(uri, "uri");
+  }
+  
+  public DeleteFile(@NonNull final String uri, final DeleteFileOptions options) {
+    this(uri);
+    this.options = options;
+  }
+  
+  /**
+   * The file to delete.
+   */
+  @Pure
+  @NonNull
+  public String getUri() {
+    return this.uri;
+  }
+  
+  /**
+   * The file to delete.
+   */
+  public void setUri(@NonNull final String uri) {
+    this.uri = Preconditions.checkNotNull(uri, "uri");
+  }
+  
+  /**
+   * Delete options.
+   */
+  @Pure
+  public DeleteFileOptions getOptions() {
+    return this.options;
+  }
+  
+  /**
+   * Delete options.
+   */
+  public void setOptions(final DeleteFileOptions options) {
+    this.options = options;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("uri", this.uri);
+    b.add("options", this.options);
+    b.add("kind", getKind());
+    b.add("annotationId", getAnnotationId());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    DeleteFile other = (DeleteFile) obj;
+    if (this.uri == null) {
+      if (other.uri != null)
+        return false;
+    } else if (!this.uri.equals(other.uri))
+      return false;
+    if (this.options == null) {
+      if (other.options != null)
+        return false;
+    } else if (!this.options.equals(other.options))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.uri== null) ? 0 : this.uri.hashCode());
+    return prime * result + ((this.options== null) ? 0 : this.options.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DeleteFileOptions.java b/java/org/eclipse/lsp4j/DeleteFileOptions.java
new file mode 100644
index 0000000..2934b84
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DeleteFileOptions.java
@@ -0,0 +1,110 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Delete file options
+ */
+@SuppressWarnings("all")
+public class DeleteFileOptions {
+  /**
+   * Delete the content recursively if a folder is denoted.
+   */
+  private Boolean recursive;
+  
+  /**
+   * Ignore the operation if the file doesn't exist.
+   */
+  private Boolean ignoreIfNotExists;
+  
+  public DeleteFileOptions() {
+  }
+  
+  public DeleteFileOptions(final Boolean recursive, final Boolean ignoreIfNotExists) {
+    this.recursive = recursive;
+    this.ignoreIfNotExists = ignoreIfNotExists;
+  }
+  
+  /**
+   * Delete the content recursively if a folder is denoted.
+   */
+  @Pure
+  public Boolean getRecursive() {
+    return this.recursive;
+  }
+  
+  /**
+   * Delete the content recursively if a folder is denoted.
+   */
+  public void setRecursive(final Boolean recursive) {
+    this.recursive = recursive;
+  }
+  
+  /**
+   * Ignore the operation if the file doesn't exist.
+   */
+  @Pure
+  public Boolean getIgnoreIfNotExists() {
+    return this.ignoreIfNotExists;
+  }
+  
+  /**
+   * Ignore the operation if the file doesn't exist.
+   */
+  public void setIgnoreIfNotExists(final Boolean ignoreIfNotExists) {
+    this.ignoreIfNotExists = ignoreIfNotExists;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("recursive", this.recursive);
+    b.add("ignoreIfNotExists", this.ignoreIfNotExists);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DeleteFileOptions other = (DeleteFileOptions) obj;
+    if (this.recursive == null) {
+      if (other.recursive != null)
+        return false;
+    } else if (!this.recursive.equals(other.recursive))
+      return false;
+    if (this.ignoreIfNotExists == null) {
+      if (other.ignoreIfNotExists != null)
+        return false;
+    } else if (!this.ignoreIfNotExists.equals(other.ignoreIfNotExists))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.recursive== null) ? 0 : this.recursive.hashCode());
+    return prime * result + ((this.ignoreIfNotExists== null) ? 0 : this.ignoreIfNotExists.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DeleteFilesParams.java b/java/org/eclipse/lsp4j/DeleteFilesParams.java
new file mode 100644
index 0000000..aa9b9da
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DeleteFilesParams.java
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.lsp4j.FileDelete;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The parameters sent in notifications/requests for user-initiated deletes
+ * of files.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class DeleteFilesParams {
+  /**
+   * An array of all files/folders deleted in this operation.
+   */
+  @NonNull
+  private List<FileDelete> files = new ArrayList<FileDelete>();
+  
+  public DeleteFilesParams() {
+  }
+  
+  public DeleteFilesParams(@NonNull final List<FileDelete> files) {
+    this.files = Preconditions.<List<FileDelete>>checkNotNull(files, "files");
+  }
+  
+  /**
+   * An array of all files/folders deleted in this operation.
+   */
+  @Pure
+  @NonNull
+  public List<FileDelete> getFiles() {
+    return this.files;
+  }
+  
+  /**
+   * An array of all files/folders deleted in this operation.
+   */
+  public void setFiles(@NonNull final List<FileDelete> files) {
+    this.files = Preconditions.checkNotNull(files, "files");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("files", this.files);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DeleteFilesParams other = (DeleteFilesParams) obj;
+    if (this.files == null) {
+      if (other.files != null)
+        return false;
+    } else if (!this.files.equals(other.files))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.files== null) ? 0 : this.files.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/Diagnostic.java b/java/org/eclipse/lsp4j/Diagnostic.java
new file mode 100644
index 0000000..cf2c396
--- /dev/null
+++ b/java/org/eclipse/lsp4j/Diagnostic.java
@@ -0,0 +1,375 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import com.google.gson.annotations.JsonAdapter;
+import java.util.List;
+import org.eclipse.lsp4j.DiagnosticCodeDescription;
+import org.eclipse.lsp4j.DiagnosticRelatedInformation;
+import org.eclipse.lsp4j.DiagnosticSeverity;
+import org.eclipse.lsp4j.DiagnosticTag;
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Represents a diagnostic, such as a compiler error or warning. Diagnostic objects are only valid in the scope of a resource.
+ */
+@SuppressWarnings("all")
+public class Diagnostic {
+  /**
+   * The range at which the message applies
+   */
+  @NonNull
+  private Range range;
+  
+  /**
+   * The diagnostic's severity. Can be omitted. If omitted it is up to the client to interpret diagnostics as error,
+   * warning, info or hint.
+   */
+  private DiagnosticSeverity severity;
+  
+  /**
+   * The diagnostic's code. Can be omitted.
+   */
+  private Either<String, Integer> code;
+  
+  /**
+   * An optional property to describe the error code.
+   * <p>
+   * Since 3.16.0
+   */
+  private DiagnosticCodeDescription codeDescription;
+  
+  /**
+   * A human-readable string describing the source of this diagnostic, e.g. 'typescript' or 'super lint'.
+   */
+  private String source;
+  
+  /**
+   * The diagnostic's message.
+   */
+  @NonNull
+  private String message;
+  
+  /**
+   * Additional metadata about the diagnostic.
+   * <p>
+   * Since 3.15.0
+   */
+  private List<DiagnosticTag> tags;
+  
+  /**
+   * An array of related diagnostic information, e.g. when symbol-names within a scope collide
+   * all definitions can be marked via this property.
+   * <p>
+   * Since 3.7.0
+   */
+  private List<DiagnosticRelatedInformation> relatedInformation;
+  
+  /**
+   * A data entry field that is preserved between a `textDocument/publishDiagnostics`
+   * notification and `textDocument/codeAction` request.
+   * <p>
+   * Since 3.16.0
+   */
+  @JsonAdapter(JsonElementTypeAdapter.Factory.class)
+  private Object data;
+  
+  public Diagnostic() {
+  }
+  
+  public Diagnostic(@NonNull final Range range, @NonNull final String message) {
+    this.range = Preconditions.<Range>checkNotNull(range, "range");
+    this.message = Preconditions.<String>checkNotNull(message, "message");
+  }
+  
+  public Diagnostic(@NonNull final Range range, @NonNull final String message, final DiagnosticSeverity severity, final String source) {
+    this(range, message);
+    this.severity = severity;
+    this.source = source;
+  }
+  
+  public Diagnostic(@NonNull final Range range, @NonNull final String message, final DiagnosticSeverity severity, final String source, final String code) {
+    this(range, message, severity, source);
+    this.setCode(code);
+  }
+  
+  /**
+   * The range at which the message applies
+   */
+  @Pure
+  @NonNull
+  public Range getRange() {
+    return this.range;
+  }
+  
+  /**
+   * The range at which the message applies
+   */
+  public void setRange(@NonNull final Range range) {
+    this.range = Preconditions.checkNotNull(range, "range");
+  }
+  
+  /**
+   * The diagnostic's severity. Can be omitted. If omitted it is up to the client to interpret diagnostics as error,
+   * warning, info or hint.
+   */
+  @Pure
+  public DiagnosticSeverity getSeverity() {
+    return this.severity;
+  }
+  
+  /**
+   * The diagnostic's severity. Can be omitted. If omitted it is up to the client to interpret diagnostics as error,
+   * warning, info or hint.
+   */
+  public void setSeverity(final DiagnosticSeverity severity) {
+    this.severity = severity;
+  }
+  
+  /**
+   * The diagnostic's code. Can be omitted.
+   */
+  @Pure
+  public Either<String, Integer> getCode() {
+    return this.code;
+  }
+  
+  /**
+   * The diagnostic's code. Can be omitted.
+   */
+  public void setCode(final Either<String, Integer> code) {
+    this.code = code;
+  }
+  
+  public void setCode(final String code) {
+    if (code == null) {
+      this.code = null;
+      return;
+    }
+    this.code = Either.forLeft(code);
+  }
+  
+  public void setCode(final Integer code) {
+    if (code == null) {
+      this.code = null;
+      return;
+    }
+    this.code = Either.forRight(code);
+  }
+  
+  /**
+   * An optional property to describe the error code.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public DiagnosticCodeDescription getCodeDescription() {
+    return this.codeDescription;
+  }
+  
+  /**
+   * An optional property to describe the error code.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setCodeDescription(final DiagnosticCodeDescription codeDescription) {
+    this.codeDescription = codeDescription;
+  }
+  
+  /**
+   * A human-readable string describing the source of this diagnostic, e.g. 'typescript' or 'super lint'.
+   */
+  @Pure
+  public String getSource() {
+    return this.source;
+  }
+  
+  /**
+   * A human-readable string describing the source of this diagnostic, e.g. 'typescript' or 'super lint'.
+   */
+  public void setSource(final String source) {
+    this.source = source;
+  }
+  
+  /**
+   * The diagnostic's message.
+   */
+  @Pure
+  @NonNull
+  public String getMessage() {
+    return this.message;
+  }
+  
+  /**
+   * The diagnostic's message.
+   */
+  public void setMessage(@NonNull final String message) {
+    this.message = Preconditions.checkNotNull(message, "message");
+  }
+  
+  /**
+   * Additional metadata about the diagnostic.
+   * <p>
+   * Since 3.15.0
+   */
+  @Pure
+  public List<DiagnosticTag> getTags() {
+    return this.tags;
+  }
+  
+  /**
+   * Additional metadata about the diagnostic.
+   * <p>
+   * Since 3.15.0
+   */
+  public void setTags(final List<DiagnosticTag> tags) {
+    this.tags = tags;
+  }
+  
+  /**
+   * An array of related diagnostic information, e.g. when symbol-names within a scope collide
+   * all definitions can be marked via this property.
+   * <p>
+   * Since 3.7.0
+   */
+  @Pure
+  public List<DiagnosticRelatedInformation> getRelatedInformation() {
+    return this.relatedInformation;
+  }
+  
+  /**
+   * An array of related diagnostic information, e.g. when symbol-names within a scope collide
+   * all definitions can be marked via this property.
+   * <p>
+   * Since 3.7.0
+   */
+  public void setRelatedInformation(final List<DiagnosticRelatedInformation> relatedInformation) {
+    this.relatedInformation = relatedInformation;
+  }
+  
+  /**
+   * A data entry field that is preserved between a `textDocument/publishDiagnostics`
+   * notification and `textDocument/codeAction` request.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public Object getData() {
+    return this.data;
+  }
+  
+  /**
+   * A data entry field that is preserved between a `textDocument/publishDiagnostics`
+   * notification and `textDocument/codeAction` request.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setData(final Object data) {
+    this.data = data;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("range", this.range);
+    b.add("severity", this.severity);
+    b.add("code", this.code);
+    b.add("codeDescription", this.codeDescription);
+    b.add("source", this.source);
+    b.add("message", this.message);
+    b.add("tags", this.tags);
+    b.add("relatedInformation", this.relatedInformation);
+    b.add("data", this.data);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    Diagnostic other = (Diagnostic) obj;
+    if (this.range == null) {
+      if (other.range != null)
+        return false;
+    } else if (!this.range.equals(other.range))
+      return false;
+    if (this.severity == null) {
+      if (other.severity != null)
+        return false;
+    } else if (!this.severity.equals(other.severity))
+      return false;
+    if (this.code == null) {
+      if (other.code != null)
+        return false;
+    } else if (!this.code.equals(other.code))
+      return false;
+    if (this.codeDescription == null) {
+      if (other.codeDescription != null)
+        return false;
+    } else if (!this.codeDescription.equals(other.codeDescription))
+      return false;
+    if (this.source == null) {
+      if (other.source != null)
+        return false;
+    } else if (!this.source.equals(other.source))
+      return false;
+    if (this.message == null) {
+      if (other.message != null)
+        return false;
+    } else if (!this.message.equals(other.message))
+      return false;
+    if (this.tags == null) {
+      if (other.tags != null)
+        return false;
+    } else if (!this.tags.equals(other.tags))
+      return false;
+    if (this.relatedInformation == null) {
+      if (other.relatedInformation != null)
+        return false;
+    } else if (!this.relatedInformation.equals(other.relatedInformation))
+      return false;
+    if (this.data == null) {
+      if (other.data != null)
+        return false;
+    } else if (!this.data.equals(other.data))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.range== null) ? 0 : this.range.hashCode());
+    result = prime * result + ((this.severity== null) ? 0 : this.severity.hashCode());
+    result = prime * result + ((this.code== null) ? 0 : this.code.hashCode());
+    result = prime * result + ((this.codeDescription== null) ? 0 : this.codeDescription.hashCode());
+    result = prime * result + ((this.source== null) ? 0 : this.source.hashCode());
+    result = prime * result + ((this.message== null) ? 0 : this.message.hashCode());
+    result = prime * result + ((this.tags== null) ? 0 : this.tags.hashCode());
+    result = prime * result + ((this.relatedInformation== null) ? 0 : this.relatedInformation.hashCode());
+    return prime * result + ((this.data== null) ? 0 : this.data.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DiagnosticCodeDescription.java b/java/org/eclipse/lsp4j/DiagnosticCodeDescription.java
new file mode 100644
index 0000000..8b52598
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DiagnosticCodeDescription.java
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Structure to capture a description for an error code.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class DiagnosticCodeDescription {
+  /**
+   * A URI to open with more information about the diagnostic error.
+   */
+  @NonNull
+  private String href;
+  
+  public DiagnosticCodeDescription() {
+  }
+  
+  public DiagnosticCodeDescription(@NonNull final String href) {
+    this.href = Preconditions.<String>checkNotNull(href, "href");
+  }
+  
+  /**
+   * A URI to open with more information about the diagnostic error.
+   */
+  @Pure
+  @NonNull
+  public String getHref() {
+    return this.href;
+  }
+  
+  /**
+   * A URI to open with more information about the diagnostic error.
+   */
+  public void setHref(@NonNull final String href) {
+    this.href = Preconditions.checkNotNull(href, "href");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("href", this.href);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DiagnosticCodeDescription other = (DiagnosticCodeDescription) obj;
+    if (this.href == null) {
+      if (other.href != null)
+        return false;
+    } else if (!this.href.equals(other.href))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.href== null) ? 0 : this.href.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DiagnosticRelatedInformation.java b/java/org/eclipse/lsp4j/DiagnosticRelatedInformation.java
new file mode 100644
index 0000000..5d0dea1
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DiagnosticRelatedInformation.java
@@ -0,0 +1,121 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.Location;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Represents a related message and source code location for a diagnostic. This should be
+ * used to point to code locations that cause or related to a diagnostics, e.g when duplicating
+ * a symbol in a scope.
+ * <p>
+ * Since 3.7.0
+ */
+@SuppressWarnings("all")
+public class DiagnosticRelatedInformation {
+  /**
+   * The location of this related diagnostic information.
+   */
+  @NonNull
+  private Location location;
+  
+  /**
+   * The message of this related diagnostic information.
+   */
+  @NonNull
+  private String message;
+  
+  public DiagnosticRelatedInformation() {
+  }
+  
+  public DiagnosticRelatedInformation(@NonNull final Location location, @NonNull final String message) {
+    this.location = Preconditions.<Location>checkNotNull(location, "location");
+    this.message = Preconditions.<String>checkNotNull(message, "message");
+  }
+  
+  /**
+   * The location of this related diagnostic information.
+   */
+  @Pure
+  @NonNull
+  public Location getLocation() {
+    return this.location;
+  }
+  
+  /**
+   * The location of this related diagnostic information.
+   */
+  public void setLocation(@NonNull final Location location) {
+    this.location = Preconditions.checkNotNull(location, "location");
+  }
+  
+  /**
+   * The message of this related diagnostic information.
+   */
+  @Pure
+  @NonNull
+  public String getMessage() {
+    return this.message;
+  }
+  
+  /**
+   * The message of this related diagnostic information.
+   */
+  public void setMessage(@NonNull final String message) {
+    this.message = Preconditions.checkNotNull(message, "message");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("location", this.location);
+    b.add("message", this.message);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DiagnosticRelatedInformation other = (DiagnosticRelatedInformation) obj;
+    if (this.location == null) {
+      if (other.location != null)
+        return false;
+    } else if (!this.location.equals(other.location))
+      return false;
+    if (this.message == null) {
+      if (other.message != null)
+        return false;
+    } else if (!this.message.equals(other.message))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.location== null) ? 0 : this.location.hashCode());
+    return prime * result + ((this.message== null) ? 0 : this.message.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DiagnosticSeverity.java b/java/org/eclipse/lsp4j/DiagnosticSeverity.java
new file mode 100644
index 0000000..4e57b3c
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DiagnosticSeverity.java
@@ -0,0 +1,53 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j;
+
+public enum DiagnosticSeverity {
+	
+	/**
+	 * Reports an error.
+	 */
+	Error(1),
+	
+	/**
+	 * Reports a warning.
+	 */
+	Warning(2),
+	
+	/**
+	 * Reports an information.
+	 */
+	Information(3),
+	
+	/**
+	 * Reports a hint.
+	 */
+	Hint(4);
+	
+	private final int value;
+	
+	DiagnosticSeverity(int value) {
+		this.value = value;
+	}
+	
+	public int getValue() {
+		return value;
+	}
+	
+	public static DiagnosticSeverity forValue(int value) {
+		DiagnosticSeverity[] allValues = DiagnosticSeverity.values();
+		if (value < 1 || value > allValues.length)
+			throw new IllegalArgumentException("Illegal enum value: " + value);
+		return allValues[value - 1];
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/DiagnosticTag.java b/java/org/eclipse/lsp4j/DiagnosticTag.java
new file mode 100644
index 0000000..f205e77
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DiagnosticTag.java
@@ -0,0 +1,53 @@
+/******************************************************************************
+ * Copyright (c) 2019 Microsoft.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+
+package org.eclipse.lsp4j;
+
+/**
+ * The diagnostic tags.
+ * 
+ * Since 3.15.0
+ */
+public enum DiagnosticTag {
+
+    /**
+     * Unused or unnecessary code.
+     *
+     * Clients are allowed to render diagnostics with this tag faded out instead of having
+     * an error squiggle.
+     */
+    Unnecessary(1),
+
+    /**
+     * Deprecated or obsolete code.
+     *
+     * Clients are allowed to rendered diagnostics with this tag strike through.
+     */
+    Deprecated(2);
+
+    private final int value;
+
+    DiagnosticTag(int value) {
+        this.value = value;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public static DiagnosticTag forValue(int value) {
+        DiagnosticTag[] allValues = DiagnosticTag.values();
+        if (value < 1 || value > allValues.length)
+            throw new IllegalArgumentException("Illegal enum value: " + value);
+        return allValues[value - 1];
+    }
+}
\ No newline at end of file
diff --git a/java/org/eclipse/lsp4j/DiagnosticsTagSupport.java b/java/org/eclipse/lsp4j/DiagnosticsTagSupport.java
new file mode 100644
index 0000000..e580ea6
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DiagnosticsTagSupport.java
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.lsp4j.DiagnosticTag;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class DiagnosticsTagSupport {
+  /**
+   * The tags supported by the client.
+   */
+  @NonNull
+  private List<DiagnosticTag> valueSet;
+  
+  public DiagnosticsTagSupport() {
+    ArrayList<DiagnosticTag> _arrayList = new ArrayList<DiagnosticTag>();
+    this.valueSet = _arrayList;
+  }
+  
+  public DiagnosticsTagSupport(@NonNull final List<DiagnosticTag> valueSet) {
+    this.valueSet = Preconditions.<List<DiagnosticTag>>checkNotNull(valueSet, "valueSet");
+  }
+  
+  /**
+   * The tags supported by the client.
+   */
+  @Pure
+  @NonNull
+  public List<DiagnosticTag> getValueSet() {
+    return this.valueSet;
+  }
+  
+  /**
+   * The tags supported by the client.
+   */
+  public void setValueSet(@NonNull final List<DiagnosticTag> valueSet) {
+    this.valueSet = Preconditions.checkNotNull(valueSet, "valueSet");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("valueSet", this.valueSet);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DiagnosticsTagSupport other = (DiagnosticsTagSupport) obj;
+    if (this.valueSet == null) {
+      if (other.valueSet != null)
+        return false;
+    } else if (!this.valueSet.equals(other.valueSet))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.valueSet== null) ? 0 : this.valueSet.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DidChangeConfigurationCapabilities.java b/java/org/eclipse/lsp4j/DidChangeConfigurationCapabilities.java
new file mode 100644
index 0000000..59a8a91
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DidChangeConfigurationCapabilities.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the `workspace/didChangeConfiguration` notification.
+ */
+@SuppressWarnings("all")
+public class DidChangeConfigurationCapabilities extends DynamicRegistrationCapabilities {
+  public DidChangeConfigurationCapabilities() {
+  }
+  
+  public DidChangeConfigurationCapabilities(final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DidChangeConfigurationParams.java b/java/org/eclipse/lsp4j/DidChangeConfigurationParams.java
new file mode 100644
index 0000000..fc1121f
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DidChangeConfigurationParams.java
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import com.google.gson.annotations.JsonAdapter;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A notification sent from the client to the server to signal the change of configuration settings.
+ */
+@SuppressWarnings("all")
+public class DidChangeConfigurationParams {
+  /**
+   * The actual changed settings.
+   */
+  @NonNull
+  @JsonAdapter(JsonElementTypeAdapter.Factory.class)
+  private Object settings;
+  
+  public DidChangeConfigurationParams() {
+  }
+  
+  public DidChangeConfigurationParams(@NonNull final Object settings) {
+    this.settings = Preconditions.<Object>checkNotNull(settings, "settings");
+  }
+  
+  /**
+   * The actual changed settings.
+   */
+  @Pure
+  @NonNull
+  public Object getSettings() {
+    return this.settings;
+  }
+  
+  /**
+   * The actual changed settings.
+   */
+  public void setSettings(@NonNull final Object settings) {
+    this.settings = Preconditions.checkNotNull(settings, "settings");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("settings", this.settings);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DidChangeConfigurationParams other = (DidChangeConfigurationParams) obj;
+    if (this.settings == null) {
+      if (other.settings != null)
+        return false;
+    } else if (!this.settings.equals(other.settings))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.settings== null) ? 0 : this.settings.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DidChangeTextDocumentParams.java b/java/org/eclipse/lsp4j/DidChangeTextDocumentParams.java
new file mode 100644
index 0000000..a1741d7
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DidChangeTextDocumentParams.java
@@ -0,0 +1,159 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.lsp4j.TextDocumentContentChangeEvent;
+import org.eclipse.lsp4j.VersionedTextDocumentIdentifier;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The document change notification is sent from the client to the server to signal changes to a text document.
+ */
+@SuppressWarnings("all")
+public class DidChangeTextDocumentParams {
+  /**
+   * The document that did change. The version number points to the version after all provided content changes have
+   * been applied.
+   */
+  @NonNull
+  private VersionedTextDocumentIdentifier textDocument;
+  
+  /**
+   * Legacy property to support protocol version 1.0 requests.
+   */
+  @Deprecated
+  private String uri;
+  
+  /**
+   * The actual content changes.
+   */
+  @NonNull
+  private List<TextDocumentContentChangeEvent> contentChanges = new ArrayList<TextDocumentContentChangeEvent>();
+  
+  public DidChangeTextDocumentParams() {
+  }
+  
+  public DidChangeTextDocumentParams(@NonNull final VersionedTextDocumentIdentifier textDocument, @NonNull final List<TextDocumentContentChangeEvent> contentChanges) {
+    this.textDocument = Preconditions.<VersionedTextDocumentIdentifier>checkNotNull(textDocument, "textDocument");
+    this.contentChanges = Preconditions.<List<TextDocumentContentChangeEvent>>checkNotNull(contentChanges, "contentChanges");
+  }
+  
+  @Deprecated
+  public DidChangeTextDocumentParams(@NonNull final VersionedTextDocumentIdentifier textDocument, final String uri, @NonNull final List<TextDocumentContentChangeEvent> contentChanges) {
+    this(textDocument, contentChanges);
+    this.uri = uri;
+  }
+  
+  /**
+   * The document that did change. The version number points to the version after all provided content changes have
+   * been applied.
+   */
+  @Pure
+  @NonNull
+  public VersionedTextDocumentIdentifier getTextDocument() {
+    return this.textDocument;
+  }
+  
+  /**
+   * The document that did change. The version number points to the version after all provided content changes have
+   * been applied.
+   */
+  public void setTextDocument(@NonNull final VersionedTextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.checkNotNull(textDocument, "textDocument");
+  }
+  
+  /**
+   * Legacy property to support protocol version 1.0 requests.
+   */
+  @Pure
+  @Deprecated
+  public String getUri() {
+    return this.uri;
+  }
+  
+  /**
+   * Legacy property to support protocol version 1.0 requests.
+   */
+  @Deprecated
+  public void setUri(final String uri) {
+    this.uri = uri;
+  }
+  
+  /**
+   * The actual content changes.
+   */
+  @Pure
+  @NonNull
+  public List<TextDocumentContentChangeEvent> getContentChanges() {
+    return this.contentChanges;
+  }
+  
+  /**
+   * The actual content changes.
+   */
+  public void setContentChanges(@NonNull final List<TextDocumentContentChangeEvent> contentChanges) {
+    this.contentChanges = Preconditions.checkNotNull(contentChanges, "contentChanges");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("textDocument", this.textDocument);
+    b.add("uri", this.uri);
+    b.add("contentChanges", this.contentChanges);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DidChangeTextDocumentParams other = (DidChangeTextDocumentParams) obj;
+    if (this.textDocument == null) {
+      if (other.textDocument != null)
+        return false;
+    } else if (!this.textDocument.equals(other.textDocument))
+      return false;
+    if (this.uri == null) {
+      if (other.uri != null)
+        return false;
+    } else if (!this.uri.equals(other.uri))
+      return false;
+    if (this.contentChanges == null) {
+      if (other.contentChanges != null)
+        return false;
+    } else if (!this.contentChanges.equals(other.contentChanges))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.textDocument== null) ? 0 : this.textDocument.hashCode());
+    result = prime * result + ((this.uri== null) ? 0 : this.uri.hashCode());
+    return prime * result + ((this.contentChanges== null) ? 0 : this.contentChanges.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DidChangeWatchedFilesCapabilities.java b/java/org/eclipse/lsp4j/DidChangeWatchedFilesCapabilities.java
new file mode 100644
index 0000000..1e78628
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DidChangeWatchedFilesCapabilities.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the `workspace/didChangeWatchedFiles` notification.
+ */
+@SuppressWarnings("all")
+public class DidChangeWatchedFilesCapabilities extends DynamicRegistrationCapabilities {
+  public DidChangeWatchedFilesCapabilities() {
+  }
+  
+  public DidChangeWatchedFilesCapabilities(final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DidChangeWatchedFilesParams.java b/java/org/eclipse/lsp4j/DidChangeWatchedFilesParams.java
new file mode 100644
index 0000000..1d442e6
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DidChangeWatchedFilesParams.java
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.lsp4j.FileEvent;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The watched files notification is sent from the client to the server when the client detects changes
+ * to file watched by the language client.
+ */
+@SuppressWarnings("all")
+public class DidChangeWatchedFilesParams {
+  /**
+   * The actual file events.
+   */
+  @NonNull
+  private List<FileEvent> changes;
+  
+  public DidChangeWatchedFilesParams() {
+    this(new ArrayList<FileEvent>());
+  }
+  
+  public DidChangeWatchedFilesParams(@NonNull final List<FileEvent> changes) {
+    this.changes = Preconditions.<List<FileEvent>>checkNotNull(changes, "changes");
+  }
+  
+  /**
+   * The actual file events.
+   */
+  @Pure
+  @NonNull
+  public List<FileEvent> getChanges() {
+    return this.changes;
+  }
+  
+  /**
+   * The actual file events.
+   */
+  public void setChanges(@NonNull final List<FileEvent> changes) {
+    this.changes = Preconditions.checkNotNull(changes, "changes");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("changes", this.changes);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DidChangeWatchedFilesParams other = (DidChangeWatchedFilesParams) obj;
+    if (this.changes == null) {
+      if (other.changes != null)
+        return false;
+    } else if (!this.changes.equals(other.changes))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.changes== null) ? 0 : this.changes.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DidChangeWatchedFilesRegistrationOptions.java b/java/org/eclipse/lsp4j/DidChangeWatchedFilesRegistrationOptions.java
new file mode 100644
index 0000000..ba37cfa
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DidChangeWatchedFilesRegistrationOptions.java
@@ -0,0 +1,83 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.FileSystemWatcher;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class DidChangeWatchedFilesRegistrationOptions {
+  /**
+   * The watchers to register.
+   */
+  @NonNull
+  private List<FileSystemWatcher> watchers;
+  
+  public DidChangeWatchedFilesRegistrationOptions() {
+  }
+  
+  public DidChangeWatchedFilesRegistrationOptions(@NonNull final List<FileSystemWatcher> watchers) {
+    this.watchers = Preconditions.<List<FileSystemWatcher>>checkNotNull(watchers, "watchers");
+  }
+  
+  /**
+   * The watchers to register.
+   */
+  @Pure
+  @NonNull
+  public List<FileSystemWatcher> getWatchers() {
+    return this.watchers;
+  }
+  
+  /**
+   * The watchers to register.
+   */
+  public void setWatchers(@NonNull final List<FileSystemWatcher> watchers) {
+    this.watchers = Preconditions.checkNotNull(watchers, "watchers");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("watchers", this.watchers);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DidChangeWatchedFilesRegistrationOptions other = (DidChangeWatchedFilesRegistrationOptions) obj;
+    if (this.watchers == null) {
+      if (other.watchers != null)
+        return false;
+    } else if (!this.watchers.equals(other.watchers))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.watchers== null) ? 0 : this.watchers.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DidChangeWorkspaceFoldersParams.java b/java/org/eclipse/lsp4j/DidChangeWorkspaceFoldersParams.java
new file mode 100644
index 0000000..a071529
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DidChangeWorkspaceFoldersParams.java
@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.WorkspaceFoldersChangeEvent;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The workspace/didChangeWorkspaceFolders notification is sent from the client to the server to
+ * inform the server about workspace folder configuration changes. The notification is sent by
+ * default if both ServerCapabilities/workspace/workspaceFolders and
+ * ClientCapabilities/workspace/workspaceFolders are true; or if the server has registered to
+ * receive this notification it first.
+ * <p>
+ * Since 3.6.0
+ */
+@SuppressWarnings("all")
+public class DidChangeWorkspaceFoldersParams {
+  /**
+   * The actual workspace folder change event.
+   */
+  @NonNull
+  private WorkspaceFoldersChangeEvent event;
+  
+  public DidChangeWorkspaceFoldersParams() {
+  }
+  
+  public DidChangeWorkspaceFoldersParams(@NonNull final WorkspaceFoldersChangeEvent event) {
+    this.event = Preconditions.<WorkspaceFoldersChangeEvent>checkNotNull(event, "event");
+  }
+  
+  /**
+   * The actual workspace folder change event.
+   */
+  @Pure
+  @NonNull
+  public WorkspaceFoldersChangeEvent getEvent() {
+    return this.event;
+  }
+  
+  /**
+   * The actual workspace folder change event.
+   */
+  public void setEvent(@NonNull final WorkspaceFoldersChangeEvent event) {
+    this.event = Preconditions.checkNotNull(event, "event");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("event", this.event);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DidChangeWorkspaceFoldersParams other = (DidChangeWorkspaceFoldersParams) obj;
+    if (this.event == null) {
+      if (other.event != null)
+        return false;
+    } else if (!this.event.equals(other.event))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.event== null) ? 0 : this.event.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DidCloseTextDocumentParams.java b/java/org/eclipse/lsp4j/DidCloseTextDocumentParams.java
new file mode 100644
index 0000000..5bae096
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DidCloseTextDocumentParams.java
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The document close notification is sent from the client to the server when the document got closed in the client.
+ * The document's truth now exists where the document's uri points to (e.g. if the document's uri is a file uri the
+ * truth now exists on disk).
+ */
+@SuppressWarnings("all")
+public class DidCloseTextDocumentParams {
+  /**
+   * The document that was closed.
+   */
+  @NonNull
+  private TextDocumentIdentifier textDocument;
+  
+  public DidCloseTextDocumentParams() {
+  }
+  
+  public DidCloseTextDocumentParams(@NonNull final TextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.<TextDocumentIdentifier>checkNotNull(textDocument, "textDocument");
+  }
+  
+  /**
+   * The document that was closed.
+   */
+  @Pure
+  @NonNull
+  public TextDocumentIdentifier getTextDocument() {
+    return this.textDocument;
+  }
+  
+  /**
+   * The document that was closed.
+   */
+  public void setTextDocument(@NonNull final TextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.checkNotNull(textDocument, "textDocument");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("textDocument", this.textDocument);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DidCloseTextDocumentParams other = (DidCloseTextDocumentParams) obj;
+    if (this.textDocument == null) {
+      if (other.textDocument != null)
+        return false;
+    } else if (!this.textDocument.equals(other.textDocument))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.textDocument== null) ? 0 : this.textDocument.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DidOpenTextDocumentParams.java b/java/org/eclipse/lsp4j/DidOpenTextDocumentParams.java
new file mode 100644
index 0000000..b1a8565
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DidOpenTextDocumentParams.java
@@ -0,0 +1,125 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.TextDocumentItem;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The document open notification is sent from the client to the server to signal newly opened text documents.
+ * The document's truth is now managed by the client and the server must not try to read the document's truth using
+ * the document's uri.
+ */
+@SuppressWarnings("all")
+public class DidOpenTextDocumentParams {
+  /**
+   * The document that was opened.
+   */
+  @NonNull
+  private TextDocumentItem textDocument;
+  
+  /**
+   * Legacy property to support protocol version 1.0 requests.
+   */
+  @Deprecated
+  private String text;
+  
+  public DidOpenTextDocumentParams() {
+  }
+  
+  public DidOpenTextDocumentParams(@NonNull final TextDocumentItem textDocument) {
+    this.textDocument = Preconditions.<TextDocumentItem>checkNotNull(textDocument, "textDocument");
+  }
+  
+  @Deprecated
+  public DidOpenTextDocumentParams(@NonNull final TextDocumentItem textDocument, final String text) {
+    this(textDocument);
+    this.text = text;
+  }
+  
+  /**
+   * The document that was opened.
+   */
+  @Pure
+  @NonNull
+  public TextDocumentItem getTextDocument() {
+    return this.textDocument;
+  }
+  
+  /**
+   * The document that was opened.
+   */
+  public void setTextDocument(@NonNull final TextDocumentItem textDocument) {
+    this.textDocument = Preconditions.checkNotNull(textDocument, "textDocument");
+  }
+  
+  /**
+   * Legacy property to support protocol version 1.0 requests.
+   */
+  @Pure
+  @Deprecated
+  public String getText() {
+    return this.text;
+  }
+  
+  /**
+   * Legacy property to support protocol version 1.0 requests.
+   */
+  @Deprecated
+  public void setText(final String text) {
+    this.text = text;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("textDocument", this.textDocument);
+    b.add("text", this.text);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DidOpenTextDocumentParams other = (DidOpenTextDocumentParams) obj;
+    if (this.textDocument == null) {
+      if (other.textDocument != null)
+        return false;
+    } else if (!this.textDocument.equals(other.textDocument))
+      return false;
+    if (this.text == null) {
+      if (other.text != null)
+        return false;
+    } else if (!this.text.equals(other.text))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.textDocument== null) ? 0 : this.textDocument.hashCode());
+    return prime * result + ((this.text== null) ? 0 : this.text.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DidSaveTextDocumentParams.java b/java/org/eclipse/lsp4j/DidSaveTextDocumentParams.java
new file mode 100644
index 0000000..8dbf122
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DidSaveTextDocumentParams.java
@@ -0,0 +1,122 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The document save notification is sent from the client to the server when the document was saved in the client.
+ */
+@SuppressWarnings("all")
+public class DidSaveTextDocumentParams {
+  /**
+   * The document that was closed.
+   */
+  @NonNull
+  private TextDocumentIdentifier textDocument;
+  
+  /**
+   * Optional the content when saved. Depends on the includeText value
+   * when the save notification was requested.
+   */
+  private String text;
+  
+  public DidSaveTextDocumentParams() {
+  }
+  
+  public DidSaveTextDocumentParams(@NonNull final TextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.<TextDocumentIdentifier>checkNotNull(textDocument, "textDocument");
+  }
+  
+  public DidSaveTextDocumentParams(@NonNull final TextDocumentIdentifier textDocument, final String text) {
+    this(textDocument);
+    this.text = text;
+  }
+  
+  /**
+   * The document that was closed.
+   */
+  @Pure
+  @NonNull
+  public TextDocumentIdentifier getTextDocument() {
+    return this.textDocument;
+  }
+  
+  /**
+   * The document that was closed.
+   */
+  public void setTextDocument(@NonNull final TextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.checkNotNull(textDocument, "textDocument");
+  }
+  
+  /**
+   * Optional the content when saved. Depends on the includeText value
+   * when the save notification was requested.
+   */
+  @Pure
+  public String getText() {
+    return this.text;
+  }
+  
+  /**
+   * Optional the content when saved. Depends on the includeText value
+   * when the save notification was requested.
+   */
+  public void setText(final String text) {
+    this.text = text;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("textDocument", this.textDocument);
+    b.add("text", this.text);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DidSaveTextDocumentParams other = (DidSaveTextDocumentParams) obj;
+    if (this.textDocument == null) {
+      if (other.textDocument != null)
+        return false;
+    } else if (!this.textDocument.equals(other.textDocument))
+      return false;
+    if (this.text == null) {
+      if (other.text != null)
+        return false;
+    } else if (!this.text.equals(other.text))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.textDocument== null) ? 0 : this.textDocument.hashCode());
+    return prime * result + ((this.text== null) ? 0 : this.text.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DocumentColorParams.java b/java/org/eclipse/lsp4j/DocumentColorParams.java
new file mode 100644
index 0000000..45dc221
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentColorParams.java
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.WorkDoneProgressAndPartialResultParams;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The document color request is sent from the client to the server to list all color references
+ * found in a given text document. Along with the range, a color value in RGB is returned.
+ * <p>
+ * Since 3.6.0
+ */
+@SuppressWarnings("all")
+public class DocumentColorParams extends WorkDoneProgressAndPartialResultParams {
+  /**
+   * The text document.
+   */
+  @NonNull
+  private TextDocumentIdentifier textDocument;
+  
+  public DocumentColorParams() {
+  }
+  
+  public DocumentColorParams(@NonNull final TextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.<TextDocumentIdentifier>checkNotNull(textDocument, "textDocument");
+  }
+  
+  /**
+   * The text document.
+   */
+  @Pure
+  @NonNull
+  public TextDocumentIdentifier getTextDocument() {
+    return this.textDocument;
+  }
+  
+  /**
+   * The text document.
+   */
+  public void setTextDocument(@NonNull final TextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.checkNotNull(textDocument, "textDocument");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("textDocument", this.textDocument);
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("partialResultToken", getPartialResultToken());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    DocumentColorParams other = (DocumentColorParams) obj;
+    if (this.textDocument == null) {
+      if (other.textDocument != null)
+        return false;
+    } else if (!this.textDocument.equals(other.textDocument))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.textDocument== null) ? 0 : this.textDocument.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DocumentFilter.java b/java/org/eclipse/lsp4j/DocumentFilter.java
new file mode 100644
index 0000000..c1fc34b
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentFilter.java
@@ -0,0 +1,138 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A document filter denotes a document through properties like language, schema or pattern.
+ */
+@SuppressWarnings("all")
+public class DocumentFilter {
+  /**
+   * A language id, like `typescript`.
+   */
+  private String language;
+  
+  /**
+   * A uri scheme, like `file` or `untitled`.
+   */
+  private String scheme;
+  
+  /**
+   * A glob pattern, like `*.{ts,js}`.
+   */
+  private String pattern;
+  
+  public DocumentFilter() {
+  }
+  
+  public DocumentFilter(final String language, final String scheme, final String pattern) {
+    this.language = language;
+    this.scheme = scheme;
+    this.pattern = pattern;
+  }
+  
+  /**
+   * A language id, like `typescript`.
+   */
+  @Pure
+  public String getLanguage() {
+    return this.language;
+  }
+  
+  /**
+   * A language id, like `typescript`.
+   */
+  public void setLanguage(final String language) {
+    this.language = language;
+  }
+  
+  /**
+   * A uri scheme, like `file` or `untitled`.
+   */
+  @Pure
+  public String getScheme() {
+    return this.scheme;
+  }
+  
+  /**
+   * A uri scheme, like `file` or `untitled`.
+   */
+  public void setScheme(final String scheme) {
+    this.scheme = scheme;
+  }
+  
+  /**
+   * A glob pattern, like `*.{ts,js}`.
+   */
+  @Pure
+  public String getPattern() {
+    return this.pattern;
+  }
+  
+  /**
+   * A glob pattern, like `*.{ts,js}`.
+   */
+  public void setPattern(final String pattern) {
+    this.pattern = pattern;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("language", this.language);
+    b.add("scheme", this.scheme);
+    b.add("pattern", this.pattern);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DocumentFilter other = (DocumentFilter) obj;
+    if (this.language == null) {
+      if (other.language != null)
+        return false;
+    } else if (!this.language.equals(other.language))
+      return false;
+    if (this.scheme == null) {
+      if (other.scheme != null)
+        return false;
+    } else if (!this.scheme.equals(other.scheme))
+      return false;
+    if (this.pattern == null) {
+      if (other.pattern != null)
+        return false;
+    } else if (!this.pattern.equals(other.pattern))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.language== null) ? 0 : this.language.hashCode());
+    result = prime * result + ((this.scheme== null) ? 0 : this.scheme.hashCode());
+    return prime * result + ((this.pattern== null) ? 0 : this.pattern.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DocumentFormattingOptions.java b/java/org/eclipse/lsp4j/DocumentFormattingOptions.java
new file mode 100644
index 0000000..d6f14ad
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentFormattingOptions.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Document formatting options.
+ */
+@SuppressWarnings("all")
+public class DocumentFormattingOptions extends AbstractWorkDoneProgressOptions {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DocumentFormattingParams.java b/java/org/eclipse/lsp4j/DocumentFormattingParams.java
new file mode 100644
index 0000000..dcc2913
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentFormattingParams.java
@@ -0,0 +1,164 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.FormattingOptions;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.WorkDoneProgressParams;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The document formatting request is sent from the server to the client to format a whole document.
+ */
+@SuppressWarnings("all")
+public class DocumentFormattingParams implements WorkDoneProgressParams {
+  /**
+   * An optional token that a server can use to report work done progress.
+   */
+  private Either<String, Integer> workDoneToken;
+  
+  /**
+   * The document to format.
+   */
+  @NonNull
+  private TextDocumentIdentifier textDocument;
+  
+  /**
+   * The format options
+   */
+  @NonNull
+  private FormattingOptions options;
+  
+  public DocumentFormattingParams() {
+  }
+  
+  public DocumentFormattingParams(@NonNull final TextDocumentIdentifier textDocument, @NonNull final FormattingOptions options) {
+    this.textDocument = Preconditions.<TextDocumentIdentifier>checkNotNull(textDocument, "textDocument");
+    this.options = Preconditions.<FormattingOptions>checkNotNull(options, "options");
+  }
+  
+  /**
+   * An optional token that a server can use to report work done progress.
+   */
+  @Pure
+  @Override
+  public Either<String, Integer> getWorkDoneToken() {
+    return this.workDoneToken;
+  }
+  
+  /**
+   * An optional token that a server can use to report work done progress.
+   */
+  public void setWorkDoneToken(final Either<String, Integer> workDoneToken) {
+    this.workDoneToken = workDoneToken;
+  }
+  
+  public void setWorkDoneToken(final String workDoneToken) {
+    if (workDoneToken == null) {
+      this.workDoneToken = null;
+      return;
+    }
+    this.workDoneToken = Either.forLeft(workDoneToken);
+  }
+  
+  public void setWorkDoneToken(final Integer workDoneToken) {
+    if (workDoneToken == null) {
+      this.workDoneToken = null;
+      return;
+    }
+    this.workDoneToken = Either.forRight(workDoneToken);
+  }
+  
+  /**
+   * The document to format.
+   */
+  @Pure
+  @NonNull
+  public TextDocumentIdentifier getTextDocument() {
+    return this.textDocument;
+  }
+  
+  /**
+   * The document to format.
+   */
+  public void setTextDocument(@NonNull final TextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.checkNotNull(textDocument, "textDocument");
+  }
+  
+  /**
+   * The format options
+   */
+  @Pure
+  @NonNull
+  public FormattingOptions getOptions() {
+    return this.options;
+  }
+  
+  /**
+   * The format options
+   */
+  public void setOptions(@NonNull final FormattingOptions options) {
+    this.options = Preconditions.checkNotNull(options, "options");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneToken", this.workDoneToken);
+    b.add("textDocument", this.textDocument);
+    b.add("options", this.options);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DocumentFormattingParams other = (DocumentFormattingParams) obj;
+    if (this.workDoneToken == null) {
+      if (other.workDoneToken != null)
+        return false;
+    } else if (!this.workDoneToken.equals(other.workDoneToken))
+      return false;
+    if (this.textDocument == null) {
+      if (other.textDocument != null)
+        return false;
+    } else if (!this.textDocument.equals(other.textDocument))
+      return false;
+    if (this.options == null) {
+      if (other.options != null)
+        return false;
+    } else if (!this.options.equals(other.options))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.workDoneToken== null) ? 0 : this.workDoneToken.hashCode());
+    result = prime * result + ((this.textDocument== null) ? 0 : this.textDocument.hashCode());
+    return prime * result + ((this.options== null) ? 0 : this.options.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DocumentFormattingRegistrationOptions.java b/java/org/eclipse/lsp4j/DocumentFormattingRegistrationOptions.java
new file mode 100644
index 0000000..a9eeb45
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentFormattingRegistrationOptions.java
@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractTextDocumentRegistrationAndWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Document formatting registration options.
+ */
+@SuppressWarnings("all")
+public class DocumentFormattingRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DocumentHighlight.java b/java/org/eclipse/lsp4j/DocumentHighlight.java
new file mode 100644
index 0000000..63bcd3f
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentHighlight.java
@@ -0,0 +1,121 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DocumentHighlightKind;
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A document highlight is a range inside a text document which deserves special attention. Usually a document highlight
+ * is visualized by changing the background color of its range.
+ */
+@SuppressWarnings("all")
+public class DocumentHighlight {
+  /**
+   * The range this highlight applies to.
+   */
+  @NonNull
+  private Range range;
+  
+  /**
+   * The highlight kind, default is {@link DocumentHighlightKind#Text}.
+   */
+  private DocumentHighlightKind kind;
+  
+  public DocumentHighlight() {
+  }
+  
+  public DocumentHighlight(@NonNull final Range range) {
+    this.range = Preconditions.<Range>checkNotNull(range, "range");
+  }
+  
+  public DocumentHighlight(@NonNull final Range range, final DocumentHighlightKind kind) {
+    this(range);
+    this.kind = kind;
+  }
+  
+  /**
+   * The range this highlight applies to.
+   */
+  @Pure
+  @NonNull
+  public Range getRange() {
+    return this.range;
+  }
+  
+  /**
+   * The range this highlight applies to.
+   */
+  public void setRange(@NonNull final Range range) {
+    this.range = Preconditions.checkNotNull(range, "range");
+  }
+  
+  /**
+   * The highlight kind, default is {@link DocumentHighlightKind#Text}.
+   */
+  @Pure
+  public DocumentHighlightKind getKind() {
+    return this.kind;
+  }
+  
+  /**
+   * The highlight kind, default is {@link DocumentHighlightKind#Text}.
+   */
+  public void setKind(final DocumentHighlightKind kind) {
+    this.kind = kind;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("range", this.range);
+    b.add("kind", this.kind);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DocumentHighlight other = (DocumentHighlight) obj;
+    if (this.range == null) {
+      if (other.range != null)
+        return false;
+    } else if (!this.range.equals(other.range))
+      return false;
+    if (this.kind == null) {
+      if (other.kind != null)
+        return false;
+    } else if (!this.kind.equals(other.kind))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.range== null) ? 0 : this.range.hashCode());
+    return prime * result + ((this.kind== null) ? 0 : this.kind.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DocumentHighlightCapabilities.java b/java/org/eclipse/lsp4j/DocumentHighlightCapabilities.java
new file mode 100644
index 0000000..0e347b0
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentHighlightCapabilities.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the `textDocument/documentHighlight`
+ */
+@SuppressWarnings("all")
+public class DocumentHighlightCapabilities extends DynamicRegistrationCapabilities {
+  public DocumentHighlightCapabilities() {
+  }
+  
+  public DocumentHighlightCapabilities(final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DocumentHighlightKind.java b/java/org/eclipse/lsp4j/DocumentHighlightKind.java
new file mode 100644
index 0000000..db787ef
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentHighlightKind.java
@@ -0,0 +1,51 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j;
+
+/**
+ * A document highlight kind.
+ */
+public enum DocumentHighlightKind {
+	
+	/**
+	 * A textual occurrence.
+	 */
+	Text(1),
+	
+	/**
+	 * Read-access of a symbol, like reading a variable.
+	 */
+	Read(2),
+	
+	/**
+	 * Write-access of a symbol, like writing to a variable.
+	 */
+	Write(3);
+	
+	private final int value;
+	
+	DocumentHighlightKind(int value) {
+		this.value = value;
+	}
+	
+	public int getValue() {
+		return value;
+	}
+	
+	public static DocumentHighlightKind forValue(int value) {
+		DocumentHighlightKind[] allValues = DocumentHighlightKind.values();
+		if (value < 1 || value > allValues.length)
+			throw new IllegalArgumentException("Illegal enum value: " + value);
+		return allValues[value - 1];
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/DocumentHighlightOptions.java b/java/org/eclipse/lsp4j/DocumentHighlightOptions.java
new file mode 100644
index 0000000..ba2f6fb
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentHighlightOptions.java
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class DocumentHighlightOptions extends AbstractWorkDoneProgressOptions {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DocumentHighlightParams.java b/java/org/eclipse/lsp4j/DocumentHighlightParams.java
new file mode 100644
index 0000000..ef75886
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentHighlightParams.java
@@ -0,0 +1,65 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.Position;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.TextDocumentPositionAndWorkDoneProgressAndPartialResultParams;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The document highlight request is sent from the client to the server to resolve a document highlights
+ * for a given text document position.
+ */
+@SuppressWarnings("all")
+public class DocumentHighlightParams extends TextDocumentPositionAndWorkDoneProgressAndPartialResultParams {
+  public DocumentHighlightParams() {
+  }
+  
+  public DocumentHighlightParams(@NonNull final TextDocumentIdentifier textDocument, @NonNull final Position position) {
+    super(textDocument, position);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("partialResultToken", getPartialResultToken());
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("textDocument", getTextDocument());
+    b.add("uri", getUri());
+    b.add("position", getPosition());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DocumentHighlightRegistrationOptions.java b/java/org/eclipse/lsp4j/DocumentHighlightRegistrationOptions.java
new file mode 100644
index 0000000..885376e
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentHighlightRegistrationOptions.java
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractTextDocumentRegistrationAndWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class DocumentHighlightRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DocumentLink.java b/java/org/eclipse/lsp4j/DocumentLink.java
new file mode 100644
index 0000000..bf3566e
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentLink.java
@@ -0,0 +1,208 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import com.google.gson.annotations.JsonAdapter;
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A document link is a range in a text document that links to an internal or external resource, like another
+ * text document or a web site.
+ */
+@SuppressWarnings("all")
+public class DocumentLink {
+  /**
+   * The range this link applies to.
+   */
+  @NonNull
+  private Range range;
+  
+  /**
+   * The uri this link points to. If missing a resolve request is sent later.
+   */
+  private String target;
+  
+  /**
+   * The tooltip text when you hover over this link.
+   * <p>
+   * If a tooltip is provided, is will be displayed in a string that includes instructions on how to
+   * trigger the link, such as `{0} (ctrl + click)`. The specific instructions vary depending on OS,
+   * user settings, and localization.
+   * <p>
+   * Since 3.15.0
+   */
+  private String tooltip;
+  
+  /**
+   * A data entry field that is preserved on a document link between a
+   * DocumentLinkRequest and a DocumentLinkResolveRequest.
+   */
+  @JsonAdapter(JsonElementTypeAdapter.Factory.class)
+  private Object data;
+  
+  public DocumentLink() {
+  }
+  
+  public DocumentLink(@NonNull final Range range) {
+    this.range = Preconditions.<Range>checkNotNull(range, "range");
+  }
+  
+  public DocumentLink(@NonNull final Range range, final String target) {
+    this(range);
+    this.target = target;
+  }
+  
+  public DocumentLink(@NonNull final Range range, final String target, final Object data) {
+    this(range, target);
+    this.data = data;
+  }
+  
+  public DocumentLink(@NonNull final Range range, final String target, final Object data, final String tooltip) {
+    this(range, target, data);
+    this.tooltip = tooltip;
+  }
+  
+  /**
+   * The range this link applies to.
+   */
+  @Pure
+  @NonNull
+  public Range getRange() {
+    return this.range;
+  }
+  
+  /**
+   * The range this link applies to.
+   */
+  public void setRange(@NonNull final Range range) {
+    this.range = Preconditions.checkNotNull(range, "range");
+  }
+  
+  /**
+   * The uri this link points to. If missing a resolve request is sent later.
+   */
+  @Pure
+  public String getTarget() {
+    return this.target;
+  }
+  
+  /**
+   * The uri this link points to. If missing a resolve request is sent later.
+   */
+  public void setTarget(final String target) {
+    this.target = target;
+  }
+  
+  /**
+   * The tooltip text when you hover over this link.
+   * <p>
+   * If a tooltip is provided, is will be displayed in a string that includes instructions on how to
+   * trigger the link, such as `{0} (ctrl + click)`. The specific instructions vary depending on OS,
+   * user settings, and localization.
+   * <p>
+   * Since 3.15.0
+   */
+  @Pure
+  public String getTooltip() {
+    return this.tooltip;
+  }
+  
+  /**
+   * The tooltip text when you hover over this link.
+   * <p>
+   * If a tooltip is provided, is will be displayed in a string that includes instructions on how to
+   * trigger the link, such as `{0} (ctrl + click)`. The specific instructions vary depending on OS,
+   * user settings, and localization.
+   * <p>
+   * Since 3.15.0
+   */
+  public void setTooltip(final String tooltip) {
+    this.tooltip = tooltip;
+  }
+  
+  /**
+   * A data entry field that is preserved on a document link between a
+   * DocumentLinkRequest and a DocumentLinkResolveRequest.
+   */
+  @Pure
+  public Object getData() {
+    return this.data;
+  }
+  
+  /**
+   * A data entry field that is preserved on a document link between a
+   * DocumentLinkRequest and a DocumentLinkResolveRequest.
+   */
+  public void setData(final Object data) {
+    this.data = data;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("range", this.range);
+    b.add("target", this.target);
+    b.add("tooltip", this.tooltip);
+    b.add("data", this.data);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DocumentLink other = (DocumentLink) obj;
+    if (this.range == null) {
+      if (other.range != null)
+        return false;
+    } else if (!this.range.equals(other.range))
+      return false;
+    if (this.target == null) {
+      if (other.target != null)
+        return false;
+    } else if (!this.target.equals(other.target))
+      return false;
+    if (this.tooltip == null) {
+      if (other.tooltip != null)
+        return false;
+    } else if (!this.tooltip.equals(other.tooltip))
+      return false;
+    if (this.data == null) {
+      if (other.data != null)
+        return false;
+    } else if (!this.data.equals(other.data))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.range== null) ? 0 : this.range.hashCode());
+    result = prime * result + ((this.target== null) ? 0 : this.target.hashCode());
+    result = prime * result + ((this.tooltip== null) ? 0 : this.tooltip.hashCode());
+    return prime * result + ((this.data== null) ? 0 : this.data.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DocumentLinkCapabilities.java b/java/org/eclipse/lsp4j/DocumentLinkCapabilities.java
new file mode 100644
index 0000000..e213bf6
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentLinkCapabilities.java
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the `textDocument/documentLink`
+ */
+@SuppressWarnings("all")
+public class DocumentLinkCapabilities extends DynamicRegistrationCapabilities {
+  /**
+   * Whether the client supports the {@link DocumentLink#tooltip} property.
+   * <p>
+   * Since 3.15.0
+   */
+  private Boolean tooltipSupport;
+  
+  public DocumentLinkCapabilities() {
+  }
+  
+  public DocumentLinkCapabilities(final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+  }
+  
+  public DocumentLinkCapabilities(final Boolean dynamicRegistration, final Boolean tooltipSupport) {
+    super(dynamicRegistration);
+    this.tooltipSupport = tooltipSupport;
+  }
+  
+  /**
+   * Whether the client supports the {@link DocumentLink#tooltip} property.
+   * <p>
+   * Since 3.15.0
+   */
+  @Pure
+  public Boolean getTooltipSupport() {
+    return this.tooltipSupport;
+  }
+  
+  /**
+   * Whether the client supports the {@link DocumentLink#tooltip} property.
+   * <p>
+   * Since 3.15.0
+   */
+  public void setTooltipSupport(final Boolean tooltipSupport) {
+    this.tooltipSupport = tooltipSupport;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("tooltipSupport", this.tooltipSupport);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    DocumentLinkCapabilities other = (DocumentLinkCapabilities) obj;
+    if (this.tooltipSupport == null) {
+      if (other.tooltipSupport != null)
+        return false;
+    } else if (!this.tooltipSupport.equals(other.tooltipSupport))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.tooltipSupport== null) ? 0 : this.tooltipSupport.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DocumentLinkOptions.java b/java/org/eclipse/lsp4j/DocumentLinkOptions.java
new file mode 100644
index 0000000..4e1ff5e
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentLinkOptions.java
@@ -0,0 +1,84 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Document link options
+ */
+@SuppressWarnings("all")
+public class DocumentLinkOptions extends AbstractWorkDoneProgressOptions {
+  /**
+   * Document links have a resolve provider as well.
+   */
+  private Boolean resolveProvider;
+  
+  public DocumentLinkOptions() {
+  }
+  
+  public DocumentLinkOptions(final Boolean resolveProvider) {
+    this.resolveProvider = resolveProvider;
+  }
+  
+  /**
+   * Document links have a resolve provider as well.
+   */
+  @Pure
+  public Boolean getResolveProvider() {
+    return this.resolveProvider;
+  }
+  
+  /**
+   * Document links have a resolve provider as well.
+   */
+  public void setResolveProvider(final Boolean resolveProvider) {
+    this.resolveProvider = resolveProvider;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("resolveProvider", this.resolveProvider);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    DocumentLinkOptions other = (DocumentLinkOptions) obj;
+    if (this.resolveProvider == null) {
+      if (other.resolveProvider != null)
+        return false;
+    } else if (!this.resolveProvider.equals(other.resolveProvider))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.resolveProvider== null) ? 0 : this.resolveProvider.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DocumentLinkParams.java b/java/org/eclipse/lsp4j/DocumentLinkParams.java
new file mode 100644
index 0000000..f45aafe
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentLinkParams.java
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.WorkDoneProgressAndPartialResultParams;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The document links request is sent from the client to the server to request the location of links in a document.
+ */
+@SuppressWarnings("all")
+public class DocumentLinkParams extends WorkDoneProgressAndPartialResultParams {
+  /**
+   * The document to provide document links for.
+   */
+  @NonNull
+  private TextDocumentIdentifier textDocument;
+  
+  public DocumentLinkParams() {
+  }
+  
+  public DocumentLinkParams(@NonNull final TextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.<TextDocumentIdentifier>checkNotNull(textDocument, "textDocument");
+  }
+  
+  /**
+   * The document to provide document links for.
+   */
+  @Pure
+  @NonNull
+  public TextDocumentIdentifier getTextDocument() {
+    return this.textDocument;
+  }
+  
+  /**
+   * The document to provide document links for.
+   */
+  public void setTextDocument(@NonNull final TextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.checkNotNull(textDocument, "textDocument");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("textDocument", this.textDocument);
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("partialResultToken", getPartialResultToken());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    DocumentLinkParams other = (DocumentLinkParams) obj;
+    if (this.textDocument == null) {
+      if (other.textDocument != null)
+        return false;
+    } else if (!this.textDocument.equals(other.textDocument))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.textDocument== null) ? 0 : this.textDocument.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DocumentLinkRegistrationOptions.java b/java/org/eclipse/lsp4j/DocumentLinkRegistrationOptions.java
new file mode 100644
index 0000000..97922fc
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentLinkRegistrationOptions.java
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractTextDocumentRegistrationAndWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class DocumentLinkRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+  /**
+   * Document links have a resolve provider as well.
+   */
+  private Boolean resolveProvider;
+  
+  public DocumentLinkRegistrationOptions() {
+  }
+  
+  public DocumentLinkRegistrationOptions(final Boolean resolveProvider) {
+    this.resolveProvider = resolveProvider;
+  }
+  
+  /**
+   * Document links have a resolve provider as well.
+   */
+  @Pure
+  public Boolean getResolveProvider() {
+    return this.resolveProvider;
+  }
+  
+  /**
+   * Document links have a resolve provider as well.
+   */
+  public void setResolveProvider(final Boolean resolveProvider) {
+    this.resolveProvider = resolveProvider;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("resolveProvider", this.resolveProvider);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    DocumentLinkRegistrationOptions other = (DocumentLinkRegistrationOptions) obj;
+    if (this.resolveProvider == null) {
+      if (other.resolveProvider != null)
+        return false;
+    } else if (!this.resolveProvider.equals(other.resolveProvider))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.resolveProvider== null) ? 0 : this.resolveProvider.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DocumentOnTypeFormattingOptions.java b/java/org/eclipse/lsp4j/DocumentOnTypeFormattingOptions.java
new file mode 100644
index 0000000..3d4fddb
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentOnTypeFormattingOptions.java
@@ -0,0 +1,119 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Format document on type options
+ */
+@SuppressWarnings("all")
+public class DocumentOnTypeFormattingOptions {
+  /**
+   * A character on which formatting should be triggered, like `}`.
+   */
+  @NonNull
+  private String firstTriggerCharacter;
+  
+  /**
+   * More trigger characters.
+   */
+  private List<String> moreTriggerCharacter;
+  
+  public DocumentOnTypeFormattingOptions() {
+  }
+  
+  public DocumentOnTypeFormattingOptions(@NonNull final String firstTriggerCharacter) {
+    this.firstTriggerCharacter = firstTriggerCharacter;
+  }
+  
+  public DocumentOnTypeFormattingOptions(@NonNull final String firstTriggerCharacter, final List<String> moreTriggerCharacter) {
+    this.firstTriggerCharacter = Preconditions.<String>checkNotNull(firstTriggerCharacter, "firstTriggerCharacter");
+    this.moreTriggerCharacter = moreTriggerCharacter;
+  }
+  
+  /**
+   * A character on which formatting should be triggered, like `}`.
+   */
+  @Pure
+  @NonNull
+  public String getFirstTriggerCharacter() {
+    return this.firstTriggerCharacter;
+  }
+  
+  /**
+   * A character on which formatting should be triggered, like `}`.
+   */
+  public void setFirstTriggerCharacter(@NonNull final String firstTriggerCharacter) {
+    this.firstTriggerCharacter = Preconditions.checkNotNull(firstTriggerCharacter, "firstTriggerCharacter");
+  }
+  
+  /**
+   * More trigger characters.
+   */
+  @Pure
+  public List<String> getMoreTriggerCharacter() {
+    return this.moreTriggerCharacter;
+  }
+  
+  /**
+   * More trigger characters.
+   */
+  public void setMoreTriggerCharacter(final List<String> moreTriggerCharacter) {
+    this.moreTriggerCharacter = moreTriggerCharacter;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("firstTriggerCharacter", this.firstTriggerCharacter);
+    b.add("moreTriggerCharacter", this.moreTriggerCharacter);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DocumentOnTypeFormattingOptions other = (DocumentOnTypeFormattingOptions) obj;
+    if (this.firstTriggerCharacter == null) {
+      if (other.firstTriggerCharacter != null)
+        return false;
+    } else if (!this.firstTriggerCharacter.equals(other.firstTriggerCharacter))
+      return false;
+    if (this.moreTriggerCharacter == null) {
+      if (other.moreTriggerCharacter != null)
+        return false;
+    } else if (!this.moreTriggerCharacter.equals(other.moreTriggerCharacter))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.firstTriggerCharacter== null) ? 0 : this.firstTriggerCharacter.hashCode());
+    return prime * result + ((this.moreTriggerCharacter== null) ? 0 : this.moreTriggerCharacter.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DocumentOnTypeFormattingParams.java b/java/org/eclipse/lsp4j/DocumentOnTypeFormattingParams.java
new file mode 100644
index 0000000..fc6957b
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentOnTypeFormattingParams.java
@@ -0,0 +1,132 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.FormattingOptions;
+import org.eclipse.lsp4j.Position;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.TextDocumentPositionParams;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The document on type formatting request is sent from the client to the server to format parts of the document during typing.
+ */
+@SuppressWarnings("all")
+public class DocumentOnTypeFormattingParams extends TextDocumentPositionParams {
+  /**
+   * The format options
+   */
+  @NonNull
+  private FormattingOptions options;
+  
+  /**
+   * The character that has been typed.
+   */
+  @NonNull
+  private String ch;
+  
+  public DocumentOnTypeFormattingParams() {
+  }
+  
+  public DocumentOnTypeFormattingParams(@NonNull final TextDocumentIdentifier textDocument, @NonNull final FormattingOptions options, @NonNull final Position position, @NonNull final String ch) {
+    super(textDocument, position);
+    this.options = Preconditions.<FormattingOptions>checkNotNull(options, "options");
+    this.ch = Preconditions.<String>checkNotNull(ch, "ch");
+  }
+  
+  @Deprecated
+  public DocumentOnTypeFormattingParams(@NonNull final Position position, @NonNull final String ch) {
+    super.setPosition(position);
+    this.ch = Preconditions.<String>checkNotNull(ch, "ch");
+  }
+  
+  /**
+   * The format options
+   */
+  @Pure
+  @NonNull
+  public FormattingOptions getOptions() {
+    return this.options;
+  }
+  
+  /**
+   * The format options
+   */
+  public void setOptions(@NonNull final FormattingOptions options) {
+    this.options = Preconditions.checkNotNull(options, "options");
+  }
+  
+  /**
+   * The character that has been typed.
+   */
+  @Pure
+  @NonNull
+  public String getCh() {
+    return this.ch;
+  }
+  
+  /**
+   * The character that has been typed.
+   */
+  public void setCh(@NonNull final String ch) {
+    this.ch = Preconditions.checkNotNull(ch, "ch");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("options", this.options);
+    b.add("ch", this.ch);
+    b.add("textDocument", getTextDocument());
+    b.add("uri", getUri());
+    b.add("position", getPosition());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    DocumentOnTypeFormattingParams other = (DocumentOnTypeFormattingParams) obj;
+    if (this.options == null) {
+      if (other.options != null)
+        return false;
+    } else if (!this.options.equals(other.options))
+      return false;
+    if (this.ch == null) {
+      if (other.ch != null)
+        return false;
+    } else if (!this.ch.equals(other.ch))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.options== null) ? 0 : this.options.hashCode());
+    return prime * result + ((this.ch== null) ? 0 : this.ch.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DocumentOnTypeFormattingRegistrationOptions.java b/java/org/eclipse/lsp4j/DocumentOnTypeFormattingRegistrationOptions.java
new file mode 100644
index 0000000..385e9c3
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentOnTypeFormattingRegistrationOptions.java
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.TextDocumentRegistrationOptions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class DocumentOnTypeFormattingRegistrationOptions extends TextDocumentRegistrationOptions {
+  /**
+   * A character on which formatting should be triggered, like `}`.
+   */
+  @NonNull
+  private String firstTriggerCharacter;
+  
+  /**
+   * More trigger characters.
+   */
+  private List<String> moreTriggerCharacter;
+  
+  public DocumentOnTypeFormattingRegistrationOptions() {
+  }
+  
+  public DocumentOnTypeFormattingRegistrationOptions(@NonNull final String firstTriggerCharacter) {
+    this.firstTriggerCharacter = Preconditions.<String>checkNotNull(firstTriggerCharacter, "firstTriggerCharacter");
+  }
+  
+  public DocumentOnTypeFormattingRegistrationOptions(@NonNull final String firstTriggerCharacter, final List<String> moreTriggerCharacter) {
+    this(firstTriggerCharacter);
+    this.moreTriggerCharacter = moreTriggerCharacter;
+  }
+  
+  /**
+   * A character on which formatting should be triggered, like `}`.
+   */
+  @Pure
+  @NonNull
+  public String getFirstTriggerCharacter() {
+    return this.firstTriggerCharacter;
+  }
+  
+  /**
+   * A character on which formatting should be triggered, like `}`.
+   */
+  public void setFirstTriggerCharacter(@NonNull final String firstTriggerCharacter) {
+    this.firstTriggerCharacter = Preconditions.checkNotNull(firstTriggerCharacter, "firstTriggerCharacter");
+  }
+  
+  /**
+   * More trigger characters.
+   */
+  @Pure
+  public List<String> getMoreTriggerCharacter() {
+    return this.moreTriggerCharacter;
+  }
+  
+  /**
+   * More trigger characters.
+   */
+  public void setMoreTriggerCharacter(final List<String> moreTriggerCharacter) {
+    this.moreTriggerCharacter = moreTriggerCharacter;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("firstTriggerCharacter", this.firstTriggerCharacter);
+    b.add("moreTriggerCharacter", this.moreTriggerCharacter);
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    DocumentOnTypeFormattingRegistrationOptions other = (DocumentOnTypeFormattingRegistrationOptions) obj;
+    if (this.firstTriggerCharacter == null) {
+      if (other.firstTriggerCharacter != null)
+        return false;
+    } else if (!this.firstTriggerCharacter.equals(other.firstTriggerCharacter))
+      return false;
+    if (this.moreTriggerCharacter == null) {
+      if (other.moreTriggerCharacter != null)
+        return false;
+    } else if (!this.moreTriggerCharacter.equals(other.moreTriggerCharacter))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.firstTriggerCharacter== null) ? 0 : this.firstTriggerCharacter.hashCode());
+    return prime * result + ((this.moreTriggerCharacter== null) ? 0 : this.moreTriggerCharacter.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DocumentRangeFormattingOptions.java b/java/org/eclipse/lsp4j/DocumentRangeFormattingOptions.java
new file mode 100644
index 0000000..7a9d270
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentRangeFormattingOptions.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Document range formatting options.
+ */
+@SuppressWarnings("all")
+public class DocumentRangeFormattingOptions extends AbstractWorkDoneProgressOptions {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DocumentRangeFormattingParams.java b/java/org/eclipse/lsp4j/DocumentRangeFormattingParams.java
new file mode 100644
index 0000000..a43fb75
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentRangeFormattingParams.java
@@ -0,0 +1,200 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.FormattingOptions;
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.WorkDoneProgressParams;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The document range formatting request is sent from the client to the server to format a given range in a document.
+ */
+@SuppressWarnings("all")
+public class DocumentRangeFormattingParams implements WorkDoneProgressParams {
+  /**
+   * An optional token that a server can use to report work done progress.
+   */
+  private Either<String, Integer> workDoneToken;
+  
+  /**
+   * The document to format.
+   */
+  @NonNull
+  private TextDocumentIdentifier textDocument;
+  
+  /**
+   * The format options
+   */
+  @NonNull
+  private FormattingOptions options;
+  
+  /**
+   * The range to format
+   */
+  @NonNull
+  private Range range;
+  
+  public DocumentRangeFormattingParams() {
+  }
+  
+  public DocumentRangeFormattingParams(@NonNull final TextDocumentIdentifier textDocument, @NonNull final FormattingOptions options, @NonNull final Range range) {
+    this.textDocument = Preconditions.<TextDocumentIdentifier>checkNotNull(textDocument, "textDocument");
+    this.options = Preconditions.<FormattingOptions>checkNotNull(options, "options");
+    this.range = Preconditions.<Range>checkNotNull(range, "range");
+  }
+  
+  @Deprecated
+  public DocumentRangeFormattingParams(@NonNull final Range range) {
+    this.range = Preconditions.<Range>checkNotNull(range, "range");
+  }
+  
+  /**
+   * An optional token that a server can use to report work done progress.
+   */
+  @Pure
+  @Override
+  public Either<String, Integer> getWorkDoneToken() {
+    return this.workDoneToken;
+  }
+  
+  /**
+   * An optional token that a server can use to report work done progress.
+   */
+  public void setWorkDoneToken(final Either<String, Integer> workDoneToken) {
+    this.workDoneToken = workDoneToken;
+  }
+  
+  public void setWorkDoneToken(final String workDoneToken) {
+    if (workDoneToken == null) {
+      this.workDoneToken = null;
+      return;
+    }
+    this.workDoneToken = Either.forLeft(workDoneToken);
+  }
+  
+  public void setWorkDoneToken(final Integer workDoneToken) {
+    if (workDoneToken == null) {
+      this.workDoneToken = null;
+      return;
+    }
+    this.workDoneToken = Either.forRight(workDoneToken);
+  }
+  
+  /**
+   * The document to format.
+   */
+  @Pure
+  @NonNull
+  public TextDocumentIdentifier getTextDocument() {
+    return this.textDocument;
+  }
+  
+  /**
+   * The document to format.
+   */
+  public void setTextDocument(@NonNull final TextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.checkNotNull(textDocument, "textDocument");
+  }
+  
+  /**
+   * The format options
+   */
+  @Pure
+  @NonNull
+  public FormattingOptions getOptions() {
+    return this.options;
+  }
+  
+  /**
+   * The format options
+   */
+  public void setOptions(@NonNull final FormattingOptions options) {
+    this.options = Preconditions.checkNotNull(options, "options");
+  }
+  
+  /**
+   * The range to format
+   */
+  @Pure
+  @NonNull
+  public Range getRange() {
+    return this.range;
+  }
+  
+  /**
+   * The range to format
+   */
+  public void setRange(@NonNull final Range range) {
+    this.range = Preconditions.checkNotNull(range, "range");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneToken", this.workDoneToken);
+    b.add("textDocument", this.textDocument);
+    b.add("options", this.options);
+    b.add("range", this.range);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DocumentRangeFormattingParams other = (DocumentRangeFormattingParams) obj;
+    if (this.workDoneToken == null) {
+      if (other.workDoneToken != null)
+        return false;
+    } else if (!this.workDoneToken.equals(other.workDoneToken))
+      return false;
+    if (this.textDocument == null) {
+      if (other.textDocument != null)
+        return false;
+    } else if (!this.textDocument.equals(other.textDocument))
+      return false;
+    if (this.options == null) {
+      if (other.options != null)
+        return false;
+    } else if (!this.options.equals(other.options))
+      return false;
+    if (this.range == null) {
+      if (other.range != null)
+        return false;
+    } else if (!this.range.equals(other.range))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.workDoneToken== null) ? 0 : this.workDoneToken.hashCode());
+    result = prime * result + ((this.textDocument== null) ? 0 : this.textDocument.hashCode());
+    result = prime * result + ((this.options== null) ? 0 : this.options.hashCode());
+    return prime * result + ((this.range== null) ? 0 : this.range.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DocumentRangeFormattingRegistrationOptions.java b/java/org/eclipse/lsp4j/DocumentRangeFormattingRegistrationOptions.java
new file mode 100644
index 0000000..a482db6
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentRangeFormattingRegistrationOptions.java
@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractTextDocumentRegistrationAndWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Document range formatting registration options.
+ */
+@SuppressWarnings("all")
+public class DocumentRangeFormattingRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DocumentSymbol.java b/java/org/eclipse/lsp4j/DocumentSymbol.java
new file mode 100644
index 0000000..b7b34ea
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentSymbol.java
@@ -0,0 +1,328 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.SymbolKind;
+import org.eclipse.lsp4j.SymbolTag;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Represents programming constructs like variables, classes, interfaces etc. that appear in a document. Document symbols can be
+ * hierarchical and they have two ranges: one that encloses its definition and one that points to its most interesting range,
+ * e.g. the range of an identifier.
+ */
+@SuppressWarnings("all")
+public class DocumentSymbol {
+  /**
+   * The name of this symbol.
+   */
+  @NonNull
+  private String name;
+  
+  /**
+   * The kind of this symbol.
+   */
+  @NonNull
+  private SymbolKind kind;
+  
+  /**
+   * The range enclosing this symbol not including leading/trailing whitespace but everything else
+   * like comments. This information is typically used to determine if the clients cursor is
+   * inside the symbol to reveal in the symbol in the UI.
+   */
+  @NonNull
+  private Range range;
+  
+  /**
+   * The range that should be selected and revealed when this symbol is being picked, e.g the name of a function.
+   * Must be contained by the {@link #range}.
+   */
+  @NonNull
+  private Range selectionRange;
+  
+  /**
+   * More detail for this symbol, e.g the signature of a function. If not provided the
+   * name is used.
+   */
+  private String detail;
+  
+  /**
+   * Tags for this document symbol.
+   * <p>
+   * Since 3.16.0
+   */
+  private List<SymbolTag> tags;
+  
+  /**
+   * Indicates if this symbol is deprecated.
+   * 
+   * @deprecated Use {@link #tags} instead if supported.
+   */
+  @Deprecated
+  private Boolean deprecated;
+  
+  /**
+   * Children of this symbol, e.g. properties of a class.
+   */
+  private List<DocumentSymbol> children;
+  
+  public DocumentSymbol() {
+  }
+  
+  public DocumentSymbol(@NonNull final String name, @NonNull final SymbolKind kind, @NonNull final Range range, @NonNull final Range selectionRange) {
+    this.name = Preconditions.<String>checkNotNull(name, "name");
+    this.kind = Preconditions.<SymbolKind>checkNotNull(kind, "kind");
+    this.range = Preconditions.<Range>checkNotNull(range, "range");
+    this.selectionRange = Preconditions.<Range>checkNotNull(selectionRange, "selectionRange");
+  }
+  
+  public DocumentSymbol(@NonNull final String name, @NonNull final SymbolKind kind, @NonNull final Range range, @NonNull final Range selectionRange, final String detail) {
+    this(name, kind, range, selectionRange);
+    this.detail = detail;
+  }
+  
+  public DocumentSymbol(@NonNull final String name, @NonNull final SymbolKind kind, @NonNull final Range range, @NonNull final Range selectionRange, final String detail, final List<DocumentSymbol> children) {
+    this(name, kind, range, selectionRange);
+    this.detail = detail;
+    this.children = children;
+  }
+  
+  /**
+   * The name of this symbol.
+   */
+  @Pure
+  @NonNull
+  public String getName() {
+    return this.name;
+  }
+  
+  /**
+   * The name of this symbol.
+   */
+  public void setName(@NonNull final String name) {
+    this.name = Preconditions.checkNotNull(name, "name");
+  }
+  
+  /**
+   * The kind of this symbol.
+   */
+  @Pure
+  @NonNull
+  public SymbolKind getKind() {
+    return this.kind;
+  }
+  
+  /**
+   * The kind of this symbol.
+   */
+  public void setKind(@NonNull final SymbolKind kind) {
+    this.kind = Preconditions.checkNotNull(kind, "kind");
+  }
+  
+  /**
+   * The range enclosing this symbol not including leading/trailing whitespace but everything else
+   * like comments. This information is typically used to determine if the clients cursor is
+   * inside the symbol to reveal in the symbol in the UI.
+   */
+  @Pure
+  @NonNull
+  public Range getRange() {
+    return this.range;
+  }
+  
+  /**
+   * The range enclosing this symbol not including leading/trailing whitespace but everything else
+   * like comments. This information is typically used to determine if the clients cursor is
+   * inside the symbol to reveal in the symbol in the UI.
+   */
+  public void setRange(@NonNull final Range range) {
+    this.range = Preconditions.checkNotNull(range, "range");
+  }
+  
+  /**
+   * The range that should be selected and revealed when this symbol is being picked, e.g the name of a function.
+   * Must be contained by the {@link #range}.
+   */
+  @Pure
+  @NonNull
+  public Range getSelectionRange() {
+    return this.selectionRange;
+  }
+  
+  /**
+   * The range that should be selected and revealed when this symbol is being picked, e.g the name of a function.
+   * Must be contained by the {@link #range}.
+   */
+  public void setSelectionRange(@NonNull final Range selectionRange) {
+    this.selectionRange = Preconditions.checkNotNull(selectionRange, "selectionRange");
+  }
+  
+  /**
+   * More detail for this symbol, e.g the signature of a function. If not provided the
+   * name is used.
+   */
+  @Pure
+  public String getDetail() {
+    return this.detail;
+  }
+  
+  /**
+   * More detail for this symbol, e.g the signature of a function. If not provided the
+   * name is used.
+   */
+  public void setDetail(final String detail) {
+    this.detail = detail;
+  }
+  
+  /**
+   * Tags for this document symbol.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public List<SymbolTag> getTags() {
+    return this.tags;
+  }
+  
+  /**
+   * Tags for this document symbol.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setTags(final List<SymbolTag> tags) {
+    this.tags = tags;
+  }
+  
+  /**
+   * Indicates if this symbol is deprecated.
+   * 
+   * @deprecated Use {@link #tags} instead if supported.
+   */
+  @Pure
+  @Deprecated
+  public Boolean getDeprecated() {
+    return this.deprecated;
+  }
+  
+  /**
+   * Indicates if this symbol is deprecated.
+   * 
+   * @deprecated Use {@link #tags} instead if supported.
+   */
+  @Deprecated
+  public void setDeprecated(final Boolean deprecated) {
+    this.deprecated = deprecated;
+  }
+  
+  /**
+   * Children of this symbol, e.g. properties of a class.
+   */
+  @Pure
+  public List<DocumentSymbol> getChildren() {
+    return this.children;
+  }
+  
+  /**
+   * Children of this symbol, e.g. properties of a class.
+   */
+  public void setChildren(final List<DocumentSymbol> children) {
+    this.children = children;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("name", this.name);
+    b.add("kind", this.kind);
+    b.add("range", this.range);
+    b.add("selectionRange", this.selectionRange);
+    b.add("detail", this.detail);
+    b.add("tags", this.tags);
+    b.add("deprecated", this.deprecated);
+    b.add("children", this.children);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DocumentSymbol other = (DocumentSymbol) obj;
+    if (this.name == null) {
+      if (other.name != null)
+        return false;
+    } else if (!this.name.equals(other.name))
+      return false;
+    if (this.kind == null) {
+      if (other.kind != null)
+        return false;
+    } else if (!this.kind.equals(other.kind))
+      return false;
+    if (this.range == null) {
+      if (other.range != null)
+        return false;
+    } else if (!this.range.equals(other.range))
+      return false;
+    if (this.selectionRange == null) {
+      if (other.selectionRange != null)
+        return false;
+    } else if (!this.selectionRange.equals(other.selectionRange))
+      return false;
+    if (this.detail == null) {
+      if (other.detail != null)
+        return false;
+    } else if (!this.detail.equals(other.detail))
+      return false;
+    if (this.tags == null) {
+      if (other.tags != null)
+        return false;
+    } else if (!this.tags.equals(other.tags))
+      return false;
+    if (this.deprecated == null) {
+      if (other.deprecated != null)
+        return false;
+    } else if (!this.deprecated.equals(other.deprecated))
+      return false;
+    if (this.children == null) {
+      if (other.children != null)
+        return false;
+    } else if (!this.children.equals(other.children))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.name== null) ? 0 : this.name.hashCode());
+    result = prime * result + ((this.kind== null) ? 0 : this.kind.hashCode());
+    result = prime * result + ((this.range== null) ? 0 : this.range.hashCode());
+    result = prime * result + ((this.selectionRange== null) ? 0 : this.selectionRange.hashCode());
+    result = prime * result + ((this.detail== null) ? 0 : this.detail.hashCode());
+    result = prime * result + ((this.tags== null) ? 0 : this.tags.hashCode());
+    result = prime * result + ((this.deprecated== null) ? 0 : this.deprecated.hashCode());
+    return prime * result + ((this.children== null) ? 0 : this.children.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DocumentSymbolCapabilities.java b/java/org/eclipse/lsp4j/DocumentSymbolCapabilities.java
new file mode 100644
index 0000000..b31f3e5
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentSymbolCapabilities.java
@@ -0,0 +1,205 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.lsp4j.SymbolKindCapabilities;
+import org.eclipse.lsp4j.SymbolTagSupportCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the `textDocument/documentSymbol`
+ */
+@SuppressWarnings("all")
+public class DocumentSymbolCapabilities extends DynamicRegistrationCapabilities {
+  /**
+   * Specific capabilities for the {@link SymbolKind}.
+   */
+  private SymbolKindCapabilities symbolKind;
+  
+  /**
+   * The client support hierarchical document symbols.
+   */
+  private Boolean hierarchicalDocumentSymbolSupport;
+  
+  /**
+   * The client supports tags on {@link SymbolInformation}. Tags are supported on
+   * {@link DocumentSymbol} if {@link #hierarchicalDocumentSymbolSupport} is set to true.
+   * Clients supporting tags have to handle unknown tags gracefully.
+   * <p>
+   * Since 3.16.0
+   */
+  private SymbolTagSupportCapabilities tagSupport;
+  
+  /**
+   * The client supports an additional label presented in the UI when
+   * registering a document symbol provider.
+   * <p>
+   * Since 3.16.0
+   */
+  private Boolean labelSupport;
+  
+  public DocumentSymbolCapabilities() {
+  }
+  
+  public DocumentSymbolCapabilities(final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+  }
+  
+  public DocumentSymbolCapabilities(final SymbolKindCapabilities symbolKind) {
+    this.symbolKind = symbolKind;
+  }
+  
+  public DocumentSymbolCapabilities(final SymbolKindCapabilities symbolKind, final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+    this.symbolKind = symbolKind;
+  }
+  
+  public DocumentSymbolCapabilities(final SymbolKindCapabilities symbolKind, final Boolean dynamicRegistration, final Boolean hierarchicalDocumentSymbolSupport) {
+    super(dynamicRegistration);
+    this.symbolKind = symbolKind;
+    this.hierarchicalDocumentSymbolSupport = hierarchicalDocumentSymbolSupport;
+  }
+  
+  /**
+   * Specific capabilities for the {@link SymbolKind}.
+   */
+  @Pure
+  public SymbolKindCapabilities getSymbolKind() {
+    return this.symbolKind;
+  }
+  
+  /**
+   * Specific capabilities for the {@link SymbolKind}.
+   */
+  public void setSymbolKind(final SymbolKindCapabilities symbolKind) {
+    this.symbolKind = symbolKind;
+  }
+  
+  /**
+   * The client support hierarchical document symbols.
+   */
+  @Pure
+  public Boolean getHierarchicalDocumentSymbolSupport() {
+    return this.hierarchicalDocumentSymbolSupport;
+  }
+  
+  /**
+   * The client support hierarchical document symbols.
+   */
+  public void setHierarchicalDocumentSymbolSupport(final Boolean hierarchicalDocumentSymbolSupport) {
+    this.hierarchicalDocumentSymbolSupport = hierarchicalDocumentSymbolSupport;
+  }
+  
+  /**
+   * The client supports tags on {@link SymbolInformation}. Tags are supported on
+   * {@link DocumentSymbol} if {@link #hierarchicalDocumentSymbolSupport} is set to true.
+   * Clients supporting tags have to handle unknown tags gracefully.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public SymbolTagSupportCapabilities getTagSupport() {
+    return this.tagSupport;
+  }
+  
+  /**
+   * The client supports tags on {@link SymbolInformation}. Tags are supported on
+   * {@link DocumentSymbol} if {@link #hierarchicalDocumentSymbolSupport} is set to true.
+   * Clients supporting tags have to handle unknown tags gracefully.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setTagSupport(final SymbolTagSupportCapabilities tagSupport) {
+    this.tagSupport = tagSupport;
+  }
+  
+  /**
+   * The client supports an additional label presented in the UI when
+   * registering a document symbol provider.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public Boolean getLabelSupport() {
+    return this.labelSupport;
+  }
+  
+  /**
+   * The client supports an additional label presented in the UI when
+   * registering a document symbol provider.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setLabelSupport(final Boolean labelSupport) {
+    this.labelSupport = labelSupport;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("symbolKind", this.symbolKind);
+    b.add("hierarchicalDocumentSymbolSupport", this.hierarchicalDocumentSymbolSupport);
+    b.add("tagSupport", this.tagSupport);
+    b.add("labelSupport", this.labelSupport);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    DocumentSymbolCapabilities other = (DocumentSymbolCapabilities) obj;
+    if (this.symbolKind == null) {
+      if (other.symbolKind != null)
+        return false;
+    } else if (!this.symbolKind.equals(other.symbolKind))
+      return false;
+    if (this.hierarchicalDocumentSymbolSupport == null) {
+      if (other.hierarchicalDocumentSymbolSupport != null)
+        return false;
+    } else if (!this.hierarchicalDocumentSymbolSupport.equals(other.hierarchicalDocumentSymbolSupport))
+      return false;
+    if (this.tagSupport == null) {
+      if (other.tagSupport != null)
+        return false;
+    } else if (!this.tagSupport.equals(other.tagSupport))
+      return false;
+    if (this.labelSupport == null) {
+      if (other.labelSupport != null)
+        return false;
+    } else if (!this.labelSupport.equals(other.labelSupport))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.symbolKind== null) ? 0 : this.symbolKind.hashCode());
+    result = prime * result + ((this.hierarchicalDocumentSymbolSupport== null) ? 0 : this.hierarchicalDocumentSymbolSupport.hashCode());
+    result = prime * result + ((this.tagSupport== null) ? 0 : this.tagSupport.hashCode());
+    return prime * result + ((this.labelSupport== null) ? 0 : this.labelSupport.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DocumentSymbolOptions.java b/java/org/eclipse/lsp4j/DocumentSymbolOptions.java
new file mode 100644
index 0000000..cff82fd
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentSymbolOptions.java
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class DocumentSymbolOptions extends AbstractWorkDoneProgressOptions {
+  /**
+   * A human-readable string that is shown when multiple outlines trees
+   * are shown for the same document.
+   * <p>
+   * Since 3.16.0
+   */
+  private String label;
+  
+  public DocumentSymbolOptions() {
+  }
+  
+  public DocumentSymbolOptions(final String label) {
+    this.label = label;
+  }
+  
+  /**
+   * A human-readable string that is shown when multiple outlines trees
+   * are shown for the same document.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public String getLabel() {
+    return this.label;
+  }
+  
+  /**
+   * A human-readable string that is shown when multiple outlines trees
+   * are shown for the same document.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setLabel(final String label) {
+    this.label = label;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("label", this.label);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    DocumentSymbolOptions other = (DocumentSymbolOptions) obj;
+    if (this.label == null) {
+      if (other.label != null)
+        return false;
+    } else if (!this.label.equals(other.label))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.label== null) ? 0 : this.label.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DocumentSymbolParams.java b/java/org/eclipse/lsp4j/DocumentSymbolParams.java
new file mode 100644
index 0000000..62b5428
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentSymbolParams.java
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.WorkDoneProgressAndPartialResultParams;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The document symbol request is sent from the client to the server to list all symbols found in a given text document.
+ */
+@SuppressWarnings("all")
+public class DocumentSymbolParams extends WorkDoneProgressAndPartialResultParams {
+  /**
+   * The text document.
+   */
+  @NonNull
+  private TextDocumentIdentifier textDocument;
+  
+  public DocumentSymbolParams() {
+  }
+  
+  public DocumentSymbolParams(@NonNull final TextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.<TextDocumentIdentifier>checkNotNull(textDocument, "textDocument");
+  }
+  
+  /**
+   * The text document.
+   */
+  @Pure
+  @NonNull
+  public TextDocumentIdentifier getTextDocument() {
+    return this.textDocument;
+  }
+  
+  /**
+   * The text document.
+   */
+  public void setTextDocument(@NonNull final TextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.checkNotNull(textDocument, "textDocument");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("textDocument", this.textDocument);
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("partialResultToken", getPartialResultToken());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    DocumentSymbolParams other = (DocumentSymbolParams) obj;
+    if (this.textDocument == null) {
+      if (other.textDocument != null)
+        return false;
+    } else if (!this.textDocument.equals(other.textDocument))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.textDocument== null) ? 0 : this.textDocument.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DocumentSymbolRegistrationOptions.java b/java/org/eclipse/lsp4j/DocumentSymbolRegistrationOptions.java
new file mode 100644
index 0000000..e7598b0
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DocumentSymbolRegistrationOptions.java
@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractTextDocumentRegistrationAndWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class DocumentSymbolRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+  /**
+   * A human-readable string that is shown when multiple outlines trees
+   * are shown for the same document.
+   * <p>
+   * Since 3.16.0
+   */
+  private String label;
+  
+  public DocumentSymbolRegistrationOptions() {
+  }
+  
+  public DocumentSymbolRegistrationOptions(final String label) {
+    this.label = label;
+  }
+  
+  /**
+   * A human-readable string that is shown when multiple outlines trees
+   * are shown for the same document.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public String getLabel() {
+    return this.label;
+  }
+  
+  /**
+   * A human-readable string that is shown when multiple outlines trees
+   * are shown for the same document.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setLabel(final String label) {
+    this.label = label;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("label", this.label);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    DocumentSymbolRegistrationOptions other = (DocumentSymbolRegistrationOptions) obj;
+    if (this.label == null) {
+      if (other.label != null)
+        return false;
+    } else if (!this.label.equals(other.label))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.label== null) ? 0 : this.label.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/DynamicRegistrationCapabilities.java b/java/org/eclipse/lsp4j/DynamicRegistrationCapabilities.java
new file mode 100644
index 0000000..7991906
--- /dev/null
+++ b/java/org/eclipse/lsp4j/DynamicRegistrationCapabilities.java
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class DynamicRegistrationCapabilities {
+  /**
+   * Supports dynamic registration.
+   */
+  private Boolean dynamicRegistration;
+  
+  public DynamicRegistrationCapabilities() {
+  }
+  
+  public DynamicRegistrationCapabilities(final Boolean dynamicRegistration) {
+    this.dynamicRegistration = dynamicRegistration;
+  }
+  
+  /**
+   * Supports dynamic registration.
+   */
+  @Pure
+  public Boolean getDynamicRegistration() {
+    return this.dynamicRegistration;
+  }
+  
+  /**
+   * Supports dynamic registration.
+   */
+  public void setDynamicRegistration(final Boolean dynamicRegistration) {
+    this.dynamicRegistration = dynamicRegistration;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("dynamicRegistration", this.dynamicRegistration);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DynamicRegistrationCapabilities other = (DynamicRegistrationCapabilities) obj;
+    if (this.dynamicRegistration == null) {
+      if (other.dynamicRegistration != null)
+        return false;
+    } else if (!this.dynamicRegistration.equals(other.dynamicRegistration))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.dynamicRegistration== null) ? 0 : this.dynamicRegistration.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ExecuteCommandCapabilities.java b/java/org/eclipse/lsp4j/ExecuteCommandCapabilities.java
new file mode 100644
index 0000000..7782024
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ExecuteCommandCapabilities.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the `workspace/executeCommand` request.
+ */
+@SuppressWarnings("all")
+public class ExecuteCommandCapabilities extends DynamicRegistrationCapabilities {
+  public ExecuteCommandCapabilities() {
+  }
+  
+  public ExecuteCommandCapabilities(final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ExecuteCommandOptions.java b/java/org/eclipse/lsp4j/ExecuteCommandOptions.java
new file mode 100644
index 0000000..a1f7527
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ExecuteCommandOptions.java
@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.lsp4j.AbstractWorkDoneProgressOptions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Execute command options.
+ */
+@SuppressWarnings("all")
+public class ExecuteCommandOptions extends AbstractWorkDoneProgressOptions {
+  /**
+   * The commands to be executed on the server
+   */
+  @NonNull
+  private List<String> commands;
+  
+  public ExecuteCommandOptions() {
+    this(new ArrayList<String>());
+  }
+  
+  public ExecuteCommandOptions(@NonNull final List<String> commands) {
+    this.commands = Preconditions.<List<String>>checkNotNull(commands, "commands");
+  }
+  
+  /**
+   * The commands to be executed on the server
+   */
+  @Pure
+  @NonNull
+  public List<String> getCommands() {
+    return this.commands;
+  }
+  
+  /**
+   * The commands to be executed on the server
+   */
+  public void setCommands(@NonNull final List<String> commands) {
+    this.commands = Preconditions.checkNotNull(commands, "commands");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("commands", this.commands);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    ExecuteCommandOptions other = (ExecuteCommandOptions) obj;
+    if (this.commands == null) {
+      if (other.commands != null)
+        return false;
+    } else if (!this.commands.equals(other.commands))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.commands== null) ? 0 : this.commands.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ExecuteCommandParams.java b/java/org/eclipse/lsp4j/ExecuteCommandParams.java
new file mode 100644
index 0000000..70cbb96
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ExecuteCommandParams.java
@@ -0,0 +1,175 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.WorkDoneProgressParams;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The workspace/executeCommand request is sent from the client to the server to trigger command
+ * execution on the server. In most cases the server creates a WorkspaceEdit structure and applies
+ * the changes to the workspace using the request workspace/applyEdit which is sent from the server
+ * to the client.
+ */
+@SuppressWarnings("all")
+public class ExecuteCommandParams implements WorkDoneProgressParams {
+  /**
+   * An optional token that a server can use to report work done progress.
+   */
+  private Either<String, Integer> workDoneToken;
+  
+  /**
+   * The identifier of the actual command handler.
+   */
+  @NonNull
+  private String command;
+  
+  /**
+   * Arguments that the command should be invoked with.
+   * The arguments are typically specified when a command is returned from the server to the client.
+   * Example requests that return a command are textDocument/codeAction or textDocument/codeLens.
+   */
+  private List<Object> arguments;
+  
+  public ExecuteCommandParams() {
+  }
+  
+  public ExecuteCommandParams(@NonNull final String command, final List<Object> arguments) {
+    this.command = Preconditions.<String>checkNotNull(command, "command");
+    this.arguments = arguments;
+  }
+  
+  public ExecuteCommandParams(@NonNull final String command, final List<Object> arguments, final Either<String, Integer> workDoneToken) {
+    this(command, arguments);
+    this.workDoneToken = workDoneToken;
+  }
+  
+  /**
+   * An optional token that a server can use to report work done progress.
+   */
+  @Pure
+  @Override
+  public Either<String, Integer> getWorkDoneToken() {
+    return this.workDoneToken;
+  }
+  
+  /**
+   * An optional token that a server can use to report work done progress.
+   */
+  public void setWorkDoneToken(final Either<String, Integer> workDoneToken) {
+    this.workDoneToken = workDoneToken;
+  }
+  
+  public void setWorkDoneToken(final String workDoneToken) {
+    if (workDoneToken == null) {
+      this.workDoneToken = null;
+      return;
+    }
+    this.workDoneToken = Either.forLeft(workDoneToken);
+  }
+  
+  public void setWorkDoneToken(final Integer workDoneToken) {
+    if (workDoneToken == null) {
+      this.workDoneToken = null;
+      return;
+    }
+    this.workDoneToken = Either.forRight(workDoneToken);
+  }
+  
+  /**
+   * The identifier of the actual command handler.
+   */
+  @Pure
+  @NonNull
+  public String getCommand() {
+    return this.command;
+  }
+  
+  /**
+   * The identifier of the actual command handler.
+   */
+  public void setCommand(@NonNull final String command) {
+    this.command = Preconditions.checkNotNull(command, "command");
+  }
+  
+  /**
+   * Arguments that the command should be invoked with.
+   * The arguments are typically specified when a command is returned from the server to the client.
+   * Example requests that return a command are textDocument/codeAction or textDocument/codeLens.
+   */
+  @Pure
+  public List<Object> getArguments() {
+    return this.arguments;
+  }
+  
+  /**
+   * Arguments that the command should be invoked with.
+   * The arguments are typically specified when a command is returned from the server to the client.
+   * Example requests that return a command are textDocument/codeAction or textDocument/codeLens.
+   */
+  public void setArguments(final List<Object> arguments) {
+    this.arguments = arguments;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneToken", this.workDoneToken);
+    b.add("command", this.command);
+    b.add("arguments", this.arguments);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ExecuteCommandParams other = (ExecuteCommandParams) obj;
+    if (this.workDoneToken == null) {
+      if (other.workDoneToken != null)
+        return false;
+    } else if (!this.workDoneToken.equals(other.workDoneToken))
+      return false;
+    if (this.command == null) {
+      if (other.command != null)
+        return false;
+    } else if (!this.command.equals(other.command))
+      return false;
+    if (this.arguments == null) {
+      if (other.arguments != null)
+        return false;
+    } else if (!this.arguments.equals(other.arguments))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.workDoneToken== null) ? 0 : this.workDoneToken.hashCode());
+    result = prime * result + ((this.command== null) ? 0 : this.command.hashCode());
+    return prime * result + ((this.arguments== null) ? 0 : this.arguments.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ExecuteCommandRegistrationOptions.java b/java/org/eclipse/lsp4j/ExecuteCommandRegistrationOptions.java
new file mode 100644
index 0000000..d2f2cca
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ExecuteCommandRegistrationOptions.java
@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.ExecuteCommandOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Execute command registration options.
+ */
+@SuppressWarnings("all")
+public class ExecuteCommandRegistrationOptions extends ExecuteCommandOptions {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("commands", getCommands());
+    b.add("workDoneProgress", getWorkDoneProgress());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/FailureHandlingKind.java b/java/org/eclipse/lsp4j/FailureHandlingKind.java
new file mode 100644
index 0000000..7b0c832
--- /dev/null
+++ b/java/org/eclipse/lsp4j/FailureHandlingKind.java
@@ -0,0 +1,48 @@
+/******************************************************************************
+ * Copyright (c) 2018 Microsoft Corporation and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+
+package org.eclipse.lsp4j;
+
+/**
+ * The kind of failure handling supported by the client.
+ */
+public final class FailureHandlingKind {
+
+	private FailureHandlingKind() {
+	}
+
+	/**
+	 * Applying the workspace change is simply aborted if one of the changes
+	 * provided fails. All operations executed before the failing operation stay
+	 * executed.
+	 */
+	public static final String Abort = "abort";
+
+	/**
+	 * All operations are executed transactional. That means they either all succeed
+	 * or no changes at all are applied to the workspace.
+	 */
+	public static final String Transactional = "transactional";
+
+	/**
+	 * If the workspace edit contains only textual file changes they are executed
+	 * transactional. If resource changes (create, rename or delete file) are part
+	 * of the change the failure handling strategy is abort.
+	 */
+	public static final String TextOnlyTransactional = "textOnlyTransactional";
+
+	/**
+	 * The client tries to undo the operations already executed. But there is no
+	 * guaruntee that this is succeeding.
+	 */
+	public static final String Undo = "undo";
+}
diff --git a/java/org/eclipse/lsp4j/FileChangeType.java b/java/org/eclipse/lsp4j/FileChangeType.java
new file mode 100644
index 0000000..cb242d8
--- /dev/null
+++ b/java/org/eclipse/lsp4j/FileChangeType.java
@@ -0,0 +1,51 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j;
+
+/**
+ * The file event type.
+ */
+public enum FileChangeType {
+	
+	/**
+	 * The file got created.
+	 */
+	Created(1),
+	
+	/**
+	 * The file got changed.
+	 */
+	Changed(2),
+	
+	/**
+	 * The file got deleted.
+	 */
+	Deleted(3);
+	
+	private final int value;
+	
+	FileChangeType(int value) {
+		this.value = value;
+	}
+	
+	public int getValue() {
+		return value;
+	}
+	
+	public static FileChangeType forValue(int value) {
+		FileChangeType[] allValues = FileChangeType.values();
+		if (value < 1 || value > allValues.length)
+			throw new IllegalArgumentException("Illegal enum value: " + value);
+		return allValues[value - 1];
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/FileCreate.java b/java/org/eclipse/lsp4j/FileCreate.java
new file mode 100644
index 0000000..bbac713
--- /dev/null
+++ b/java/org/eclipse/lsp4j/FileCreate.java
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Represents information on a file/folder create.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class FileCreate {
+  /**
+   * A file:// URI for the location of the file/folder being created.
+   */
+  @NonNull
+  private String uri;
+  
+  public FileCreate() {
+  }
+  
+  public FileCreate(@NonNull final String uri) {
+    this.uri = Preconditions.<String>checkNotNull(uri, "uri");
+  }
+  
+  /**
+   * A file:// URI for the location of the file/folder being created.
+   */
+  @Pure
+  @NonNull
+  public String getUri() {
+    return this.uri;
+  }
+  
+  /**
+   * A file:// URI for the location of the file/folder being created.
+   */
+  public void setUri(@NonNull final String uri) {
+    this.uri = Preconditions.checkNotNull(uri, "uri");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("uri", this.uri);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    FileCreate other = (FileCreate) obj;
+    if (this.uri == null) {
+      if (other.uri != null)
+        return false;
+    } else if (!this.uri.equals(other.uri))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.uri== null) ? 0 : this.uri.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/FileDelete.java b/java/org/eclipse/lsp4j/FileDelete.java
new file mode 100644
index 0000000..dc1762b
--- /dev/null
+++ b/java/org/eclipse/lsp4j/FileDelete.java
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Represents information on a file/folder delete.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class FileDelete {
+  /**
+   * A file:// URI for the location of the file/folder being deleted.
+   */
+  @NonNull
+  private String uri;
+  
+  public FileDelete() {
+  }
+  
+  public FileDelete(@NonNull final String uri) {
+    this.uri = Preconditions.<String>checkNotNull(uri, "uri");
+  }
+  
+  /**
+   * A file:// URI for the location of the file/folder being deleted.
+   */
+  @Pure
+  @NonNull
+  public String getUri() {
+    return this.uri;
+  }
+  
+  /**
+   * A file:// URI for the location of the file/folder being deleted.
+   */
+  public void setUri(@NonNull final String uri) {
+    this.uri = Preconditions.checkNotNull(uri, "uri");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("uri", this.uri);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    FileDelete other = (FileDelete) obj;
+    if (this.uri == null) {
+      if (other.uri != null)
+        return false;
+    } else if (!this.uri.equals(other.uri))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.uri== null) ? 0 : this.uri.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/FileEvent.java b/java/org/eclipse/lsp4j/FileEvent.java
new file mode 100644
index 0000000..218d85f
--- /dev/null
+++ b/java/org/eclipse/lsp4j/FileEvent.java
@@ -0,0 +1,117 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.FileChangeType;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * An event describing a file change.
+ */
+@SuppressWarnings("all")
+public class FileEvent {
+  /**
+   * The file's uri.
+   */
+  @NonNull
+  private String uri;
+  
+  /**
+   * The change type.
+   */
+  @NonNull
+  private FileChangeType type;
+  
+  public FileEvent() {
+  }
+  
+  public FileEvent(@NonNull final String uri, @NonNull final FileChangeType type) {
+    this.uri = Preconditions.<String>checkNotNull(uri, "uri");
+    this.type = Preconditions.<FileChangeType>checkNotNull(type, "type");
+  }
+  
+  /**
+   * The file's uri.
+   */
+  @Pure
+  @NonNull
+  public String getUri() {
+    return this.uri;
+  }
+  
+  /**
+   * The file's uri.
+   */
+  public void setUri(@NonNull final String uri) {
+    this.uri = Preconditions.checkNotNull(uri, "uri");
+  }
+  
+  /**
+   * The change type.
+   */
+  @Pure
+  @NonNull
+  public FileChangeType getType() {
+    return this.type;
+  }
+  
+  /**
+   * The change type.
+   */
+  public void setType(@NonNull final FileChangeType type) {
+    this.type = Preconditions.checkNotNull(type, "type");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("uri", this.uri);
+    b.add("type", this.type);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    FileEvent other = (FileEvent) obj;
+    if (this.uri == null) {
+      if (other.uri != null)
+        return false;
+    } else if (!this.uri.equals(other.uri))
+      return false;
+    if (this.type == null) {
+      if (other.type != null)
+        return false;
+    } else if (!this.type.equals(other.type))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.uri== null) ? 0 : this.uri.hashCode());
+    return prime * result + ((this.type== null) ? 0 : this.type.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/FileOperationFilter.java b/java/org/eclipse/lsp4j/FileOperationFilter.java
new file mode 100644
index 0000000..7499af2
--- /dev/null
+++ b/java/org/eclipse/lsp4j/FileOperationFilter.java
@@ -0,0 +1,122 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.FileOperationPattern;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A filter to describe in which file operation requests or notifications
+ * the server is interested in.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class FileOperationFilter {
+  /**
+   * The actual file operation pattern.
+   */
+  @NonNull
+  private FileOperationPattern pattern;
+  
+  /**
+   * A Uri like {@code file} or {@code untitled}.
+   */
+  private String scheme;
+  
+  public FileOperationFilter() {
+  }
+  
+  public FileOperationFilter(@NonNull final FileOperationPattern pattern) {
+    this.pattern = Preconditions.<FileOperationPattern>checkNotNull(pattern, "pattern");
+  }
+  
+  public FileOperationFilter(@NonNull final FileOperationPattern pattern, final String scheme) {
+    this(pattern);
+    this.scheme = scheme;
+  }
+  
+  /**
+   * The actual file operation pattern.
+   */
+  @Pure
+  @NonNull
+  public FileOperationPattern getPattern() {
+    return this.pattern;
+  }
+  
+  /**
+   * The actual file operation pattern.
+   */
+  public void setPattern(@NonNull final FileOperationPattern pattern) {
+    this.pattern = Preconditions.checkNotNull(pattern, "pattern");
+  }
+  
+  /**
+   * A Uri like {@code file} or {@code untitled}.
+   */
+  @Pure
+  public String getScheme() {
+    return this.scheme;
+  }
+  
+  /**
+   * A Uri like {@code file} or {@code untitled}.
+   */
+  public void setScheme(final String scheme) {
+    this.scheme = scheme;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("pattern", this.pattern);
+    b.add("scheme", this.scheme);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    FileOperationFilter other = (FileOperationFilter) obj;
+    if (this.pattern == null) {
+      if (other.pattern != null)
+        return false;
+    } else if (!this.pattern.equals(other.pattern))
+      return false;
+    if (this.scheme == null) {
+      if (other.scheme != null)
+        return false;
+    } else if (!this.scheme.equals(other.scheme))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.pattern== null) ? 0 : this.pattern.hashCode());
+    return prime * result + ((this.scheme== null) ? 0 : this.scheme.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/FileOperationOptions.java b/java/org/eclipse/lsp4j/FileOperationOptions.java
new file mode 100644
index 0000000..9e59629
--- /dev/null
+++ b/java/org/eclipse/lsp4j/FileOperationOptions.java
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.lsp4j.FileOperationFilter;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The options for file operations.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class FileOperationOptions {
+  /**
+   * The actual filters.
+   */
+  @NonNull
+  private List<FileOperationFilter> filters = new ArrayList<FileOperationFilter>();
+  
+  public FileOperationOptions() {
+  }
+  
+  public FileOperationOptions(@NonNull final List<FileOperationFilter> filters) {
+    this.filters = Preconditions.<List<FileOperationFilter>>checkNotNull(filters, "filters");
+  }
+  
+  /**
+   * The actual filters.
+   */
+  @Pure
+  @NonNull
+  public List<FileOperationFilter> getFilters() {
+    return this.filters;
+  }
+  
+  /**
+   * The actual filters.
+   */
+  public void setFilters(@NonNull final List<FileOperationFilter> filters) {
+    this.filters = Preconditions.checkNotNull(filters, "filters");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("filters", this.filters);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    FileOperationOptions other = (FileOperationOptions) obj;
+    if (this.filters == null) {
+      if (other.filters != null)
+        return false;
+    } else if (!this.filters.equals(other.filters))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.filters== null) ? 0 : this.filters.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/FileOperationPattern.java b/java/org/eclipse/lsp4j/FileOperationPattern.java
new file mode 100644
index 0000000..3eb5e61
--- /dev/null
+++ b/java/org/eclipse/lsp4j/FileOperationPattern.java
@@ -0,0 +1,180 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.FileOperationPatternOptions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A pattern to describe in which file operation requests or notifications
+ * the server is interested in.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class FileOperationPattern {
+  /**
+   * The glob pattern to match. Glob patterns can have the following syntax:
+   * <ul>
+   * <li>`*` to match one or more characters in a path segment
+   * <li>`?` to match on one character in a path segment
+   * <li>`**` to match any number of path segments, including none
+   * <li>`{}` to group sub patterns into an OR expression. (e.g. `**​/*.{ts,js}` matches all TypeScript and JavaScript files)
+   * <li>`[]` to declare a range of characters to match in a path segment (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)
+   * <li>`[!...]` to negate a range of characters to match in a path segment (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not `example.0`)
+   * </ul>
+   */
+  @NonNull
+  private String glob;
+  
+  /**
+   * Whether to match files or folders with this pattern.
+   * <p>
+   * Matches both if undefined.
+   * <p>
+   * See {@link FileOperationPatternKind} for allowed values.
+   */
+  private String matches;
+  
+  /**
+   * Additional options used during matching.
+   */
+  private FileOperationPatternOptions options;
+  
+  public FileOperationPattern() {
+  }
+  
+  public FileOperationPattern(@NonNull final String glob) {
+    this.glob = Preconditions.<String>checkNotNull(glob, "glob");
+  }
+  
+  /**
+   * The glob pattern to match. Glob patterns can have the following syntax:
+   * <ul>
+   * <li>`*` to match one or more characters in a path segment
+   * <li>`?` to match on one character in a path segment
+   * <li>`**` to match any number of path segments, including none
+   * <li>`{}` to group sub patterns into an OR expression. (e.g. `**​/*.{ts,js}` matches all TypeScript and JavaScript files)
+   * <li>`[]` to declare a range of characters to match in a path segment (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)
+   * <li>`[!...]` to negate a range of characters to match in a path segment (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not `example.0`)
+   * </ul>
+   */
+  @Pure
+  @NonNull
+  public String getGlob() {
+    return this.glob;
+  }
+  
+  /**
+   * The glob pattern to match. Glob patterns can have the following syntax:
+   * <ul>
+   * <li>`*` to match one or more characters in a path segment
+   * <li>`?` to match on one character in a path segment
+   * <li>`**` to match any number of path segments, including none
+   * <li>`{}` to group sub patterns into an OR expression. (e.g. `**​/*.{ts,js}` matches all TypeScript and JavaScript files)
+   * <li>`[]` to declare a range of characters to match in a path segment (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)
+   * <li>`[!...]` to negate a range of characters to match in a path segment (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not `example.0`)
+   * </ul>
+   */
+  public void setGlob(@NonNull final String glob) {
+    this.glob = Preconditions.checkNotNull(glob, "glob");
+  }
+  
+  /**
+   * Whether to match files or folders with this pattern.
+   * <p>
+   * Matches both if undefined.
+   * <p>
+   * See {@link FileOperationPatternKind} for allowed values.
+   */
+  @Pure
+  public String getMatches() {
+    return this.matches;
+  }
+  
+  /**
+   * Whether to match files or folders with this pattern.
+   * <p>
+   * Matches both if undefined.
+   * <p>
+   * See {@link FileOperationPatternKind} for allowed values.
+   */
+  public void setMatches(final String matches) {
+    this.matches = matches;
+  }
+  
+  /**
+   * Additional options used during matching.
+   */
+  @Pure
+  public FileOperationPatternOptions getOptions() {
+    return this.options;
+  }
+  
+  /**
+   * Additional options used during matching.
+   */
+  public void setOptions(final FileOperationPatternOptions options) {
+    this.options = options;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("glob", this.glob);
+    b.add("matches", this.matches);
+    b.add("options", this.options);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    FileOperationPattern other = (FileOperationPattern) obj;
+    if (this.glob == null) {
+      if (other.glob != null)
+        return false;
+    } else if (!this.glob.equals(other.glob))
+      return false;
+    if (this.matches == null) {
+      if (other.matches != null)
+        return false;
+    } else if (!this.matches.equals(other.matches))
+      return false;
+    if (this.options == null) {
+      if (other.options != null)
+        return false;
+    } else if (!this.options.equals(other.options))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.glob== null) ? 0 : this.glob.hashCode());
+    result = prime * result + ((this.matches== null) ? 0 : this.matches.hashCode());
+    return prime * result + ((this.options== null) ? 0 : this.options.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/FileOperationPatternKind.java b/java/org/eclipse/lsp4j/FileOperationPatternKind.java
new file mode 100644
index 0000000..0deda28
--- /dev/null
+++ b/java/org/eclipse/lsp4j/FileOperationPatternKind.java
@@ -0,0 +1,34 @@
+/******************************************************************************
+ * Copyright (c) 2020 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j;
+
+/**
+ * A pattern kind describing if a glob pattern matches a file a folder or
+ * both.
+ *
+ * Since 3.16.0
+ */
+public final class FileOperationPatternKind {
+
+	private FileOperationPatternKind() {
+	}
+
+	/**
+	 * The pattern matches a file only.
+	 */
+	public static final String File = "file";
+
+	/**
+	 * The pattern matches a folder only.
+	 */
+	public static final String Folder = "folder";
+}
diff --git a/java/org/eclipse/lsp4j/FileOperationPatternOptions.java b/java/org/eclipse/lsp4j/FileOperationPatternOptions.java
new file mode 100644
index 0000000..4000651
--- /dev/null
+++ b/java/org/eclipse/lsp4j/FileOperationPatternOptions.java
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Matching options for the file operation pattern.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class FileOperationPatternOptions {
+  /**
+   * The pattern should be matched ignoring casing.
+   */
+  private Boolean ignoreCase;
+  
+  public FileOperationPatternOptions() {
+  }
+  
+  public FileOperationPatternOptions(final Boolean ignoreCase) {
+    this.ignoreCase = ignoreCase;
+  }
+  
+  /**
+   * The pattern should be matched ignoring casing.
+   */
+  @Pure
+  public Boolean getIgnoreCase() {
+    return this.ignoreCase;
+  }
+  
+  /**
+   * The pattern should be matched ignoring casing.
+   */
+  public void setIgnoreCase(final Boolean ignoreCase) {
+    this.ignoreCase = ignoreCase;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("ignoreCase", this.ignoreCase);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    FileOperationPatternOptions other = (FileOperationPatternOptions) obj;
+    if (this.ignoreCase == null) {
+      if (other.ignoreCase != null)
+        return false;
+    } else if (!this.ignoreCase.equals(other.ignoreCase))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.ignoreCase== null) ? 0 : this.ignoreCase.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/FileOperationsServerCapabilities.java b/java/org/eclipse/lsp4j/FileOperationsServerCapabilities.java
new file mode 100644
index 0000000..9c398b9
--- /dev/null
+++ b/java/org/eclipse/lsp4j/FileOperationsServerCapabilities.java
@@ -0,0 +1,216 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.FileOperationOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The server is interested in file notifications/requests.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class FileOperationsServerCapabilities {
+  /**
+   * The server is interested in receiving didCreateFiles notifications.
+   */
+  private FileOperationOptions didCreate;
+  
+  /**
+   * The server is interested in receiving willCreateFiles requests.
+   */
+  private FileOperationOptions willCreate;
+  
+  /**
+   * The server is interested in receiving didRenameFiles notifications.
+   */
+  private FileOperationOptions didRename;
+  
+  /**
+   * The server is interested in receiving willRenameFiles requests.
+   */
+  private FileOperationOptions willRename;
+  
+  /**
+   * The server is interested in receiving didDeleteFiles file notifications.
+   */
+  private FileOperationOptions didDelete;
+  
+  /**
+   * The server is interested in receiving willDeleteFiles file requests.
+   */
+  private FileOperationOptions willDelete;
+  
+  public FileOperationsServerCapabilities() {
+  }
+  
+  /**
+   * The server is interested in receiving didCreateFiles notifications.
+   */
+  @Pure
+  public FileOperationOptions getDidCreate() {
+    return this.didCreate;
+  }
+  
+  /**
+   * The server is interested in receiving didCreateFiles notifications.
+   */
+  public void setDidCreate(final FileOperationOptions didCreate) {
+    this.didCreate = didCreate;
+  }
+  
+  /**
+   * The server is interested in receiving willCreateFiles requests.
+   */
+  @Pure
+  public FileOperationOptions getWillCreate() {
+    return this.willCreate;
+  }
+  
+  /**
+   * The server is interested in receiving willCreateFiles requests.
+   */
+  public void setWillCreate(final FileOperationOptions willCreate) {
+    this.willCreate = willCreate;
+  }
+  
+  /**
+   * The server is interested in receiving didRenameFiles notifications.
+   */
+  @Pure
+  public FileOperationOptions getDidRename() {
+    return this.didRename;
+  }
+  
+  /**
+   * The server is interested in receiving didRenameFiles notifications.
+   */
+  public void setDidRename(final FileOperationOptions didRename) {
+    this.didRename = didRename;
+  }
+  
+  /**
+   * The server is interested in receiving willRenameFiles requests.
+   */
+  @Pure
+  public FileOperationOptions getWillRename() {
+    return this.willRename;
+  }
+  
+  /**
+   * The server is interested in receiving willRenameFiles requests.
+   */
+  public void setWillRename(final FileOperationOptions willRename) {
+    this.willRename = willRename;
+  }
+  
+  /**
+   * The server is interested in receiving didDeleteFiles file notifications.
+   */
+  @Pure
+  public FileOperationOptions getDidDelete() {
+    return this.didDelete;
+  }
+  
+  /**
+   * The server is interested in receiving didDeleteFiles file notifications.
+   */
+  public void setDidDelete(final FileOperationOptions didDelete) {
+    this.didDelete = didDelete;
+  }
+  
+  /**
+   * The server is interested in receiving willDeleteFiles file requests.
+   */
+  @Pure
+  public FileOperationOptions getWillDelete() {
+    return this.willDelete;
+  }
+  
+  /**
+   * The server is interested in receiving willDeleteFiles file requests.
+   */
+  public void setWillDelete(final FileOperationOptions willDelete) {
+    this.willDelete = willDelete;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("didCreate", this.didCreate);
+    b.add("willCreate", this.willCreate);
+    b.add("didRename", this.didRename);
+    b.add("willRename", this.willRename);
+    b.add("didDelete", this.didDelete);
+    b.add("willDelete", this.willDelete);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    FileOperationsServerCapabilities other = (FileOperationsServerCapabilities) obj;
+    if (this.didCreate == null) {
+      if (other.didCreate != null)
+        return false;
+    } else if (!this.didCreate.equals(other.didCreate))
+      return false;
+    if (this.willCreate == null) {
+      if (other.willCreate != null)
+        return false;
+    } else if (!this.willCreate.equals(other.willCreate))
+      return false;
+    if (this.didRename == null) {
+      if (other.didRename != null)
+        return false;
+    } else if (!this.didRename.equals(other.didRename))
+      return false;
+    if (this.willRename == null) {
+      if (other.willRename != null)
+        return false;
+    } else if (!this.willRename.equals(other.willRename))
+      return false;
+    if (this.didDelete == null) {
+      if (other.didDelete != null)
+        return false;
+    } else if (!this.didDelete.equals(other.didDelete))
+      return false;
+    if (this.willDelete == null) {
+      if (other.willDelete != null)
+        return false;
+    } else if (!this.willDelete.equals(other.willDelete))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.didCreate== null) ? 0 : this.didCreate.hashCode());
+    result = prime * result + ((this.willCreate== null) ? 0 : this.willCreate.hashCode());
+    result = prime * result + ((this.didRename== null) ? 0 : this.didRename.hashCode());
+    result = prime * result + ((this.willRename== null) ? 0 : this.willRename.hashCode());
+    result = prime * result + ((this.didDelete== null) ? 0 : this.didDelete.hashCode());
+    return prime * result + ((this.willDelete== null) ? 0 : this.willDelete.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/FileOperationsWorkspaceCapabilities.java b/java/org/eclipse/lsp4j/FileOperationsWorkspaceCapabilities.java
new file mode 100644
index 0000000..444362d
--- /dev/null
+++ b/java/org/eclipse/lsp4j/FileOperationsWorkspaceCapabilities.java
@@ -0,0 +1,219 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The client has support for file requests/notifications.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class FileOperationsWorkspaceCapabilities extends DynamicRegistrationCapabilities {
+  /**
+   * The client has support for sending didCreateFiles notifications.
+   */
+  private Boolean didCreate;
+  
+  /**
+   * The client has support for sending willCreateFiles requests.
+   */
+  private Boolean willCreate;
+  
+  /**
+   * The client has support for sending didRenameFiles notifications.
+   */
+  private Boolean didRename;
+  
+  /**
+   * The client has support for sending willRenameFiles requests.
+   */
+  private Boolean willRename;
+  
+  /**
+   * The client has support for sending didDeleteFiles notifications.
+   */
+  private Boolean didDelete;
+  
+  /**
+   * The client has support for sending willDeleteFiles requests.
+   */
+  private Boolean willDelete;
+  
+  public FileOperationsWorkspaceCapabilities() {
+  }
+  
+  /**
+   * The client has support for sending didCreateFiles notifications.
+   */
+  @Pure
+  public Boolean getDidCreate() {
+    return this.didCreate;
+  }
+  
+  /**
+   * The client has support for sending didCreateFiles notifications.
+   */
+  public void setDidCreate(final Boolean didCreate) {
+    this.didCreate = didCreate;
+  }
+  
+  /**
+   * The client has support for sending willCreateFiles requests.
+   */
+  @Pure
+  public Boolean getWillCreate() {
+    return this.willCreate;
+  }
+  
+  /**
+   * The client has support for sending willCreateFiles requests.
+   */
+  public void setWillCreate(final Boolean willCreate) {
+    this.willCreate = willCreate;
+  }
+  
+  /**
+   * The client has support for sending didRenameFiles notifications.
+   */
+  @Pure
+  public Boolean getDidRename() {
+    return this.didRename;
+  }
+  
+  /**
+   * The client has support for sending didRenameFiles notifications.
+   */
+  public void setDidRename(final Boolean didRename) {
+    this.didRename = didRename;
+  }
+  
+  /**
+   * The client has support for sending willRenameFiles requests.
+   */
+  @Pure
+  public Boolean getWillRename() {
+    return this.willRename;
+  }
+  
+  /**
+   * The client has support for sending willRenameFiles requests.
+   */
+  public void setWillRename(final Boolean willRename) {
+    this.willRename = willRename;
+  }
+  
+  /**
+   * The client has support for sending didDeleteFiles notifications.
+   */
+  @Pure
+  public Boolean getDidDelete() {
+    return this.didDelete;
+  }
+  
+  /**
+   * The client has support for sending didDeleteFiles notifications.
+   */
+  public void setDidDelete(final Boolean didDelete) {
+    this.didDelete = didDelete;
+  }
+  
+  /**
+   * The client has support for sending willDeleteFiles requests.
+   */
+  @Pure
+  public Boolean getWillDelete() {
+    return this.willDelete;
+  }
+  
+  /**
+   * The client has support for sending willDeleteFiles requests.
+   */
+  public void setWillDelete(final Boolean willDelete) {
+    this.willDelete = willDelete;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("didCreate", this.didCreate);
+    b.add("willCreate", this.willCreate);
+    b.add("didRename", this.didRename);
+    b.add("willRename", this.willRename);
+    b.add("didDelete", this.didDelete);
+    b.add("willDelete", this.willDelete);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    FileOperationsWorkspaceCapabilities other = (FileOperationsWorkspaceCapabilities) obj;
+    if (this.didCreate == null) {
+      if (other.didCreate != null)
+        return false;
+    } else if (!this.didCreate.equals(other.didCreate))
+      return false;
+    if (this.willCreate == null) {
+      if (other.willCreate != null)
+        return false;
+    } else if (!this.willCreate.equals(other.willCreate))
+      return false;
+    if (this.didRename == null) {
+      if (other.didRename != null)
+        return false;
+    } else if (!this.didRename.equals(other.didRename))
+      return false;
+    if (this.willRename == null) {
+      if (other.willRename != null)
+        return false;
+    } else if (!this.willRename.equals(other.willRename))
+      return false;
+    if (this.didDelete == null) {
+      if (other.didDelete != null)
+        return false;
+    } else if (!this.didDelete.equals(other.didDelete))
+      return false;
+    if (this.willDelete == null) {
+      if (other.willDelete != null)
+        return false;
+    } else if (!this.willDelete.equals(other.willDelete))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.didCreate== null) ? 0 : this.didCreate.hashCode());
+    result = prime * result + ((this.willCreate== null) ? 0 : this.willCreate.hashCode());
+    result = prime * result + ((this.didRename== null) ? 0 : this.didRename.hashCode());
+    result = prime * result + ((this.willRename== null) ? 0 : this.willRename.hashCode());
+    result = prime * result + ((this.didDelete== null) ? 0 : this.didDelete.hashCode());
+    return prime * result + ((this.willDelete== null) ? 0 : this.willDelete.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/FileRename.java b/java/org/eclipse/lsp4j/FileRename.java
new file mode 100644
index 0000000..c68a3c1
--- /dev/null
+++ b/java/org/eclipse/lsp4j/FileRename.java
@@ -0,0 +1,118 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Represents information on a file/folder rename.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class FileRename {
+  /**
+   * A file:// URI for the original location of the file/folder being renamed.
+   */
+  @NonNull
+  private String oldUri;
+  
+  /**
+   * A file:// URI for the new location of the file/folder being renamed.
+   */
+  @NonNull
+  private String newUri;
+  
+  public FileRename() {
+  }
+  
+  public FileRename(@NonNull final String oldUri, @NonNull final String newUri) {
+    this.oldUri = Preconditions.<String>checkNotNull(oldUri, "oldUri");
+    this.newUri = Preconditions.<String>checkNotNull(newUri, "newUri");
+  }
+  
+  /**
+   * A file:// URI for the original location of the file/folder being renamed.
+   */
+  @Pure
+  @NonNull
+  public String getOldUri() {
+    return this.oldUri;
+  }
+  
+  /**
+   * A file:// URI for the original location of the file/folder being renamed.
+   */
+  public void setOldUri(@NonNull final String oldUri) {
+    this.oldUri = Preconditions.checkNotNull(oldUri, "oldUri");
+  }
+  
+  /**
+   * A file:// URI for the new location of the file/folder being renamed.
+   */
+  @Pure
+  @NonNull
+  public String getNewUri() {
+    return this.newUri;
+  }
+  
+  /**
+   * A file:// URI for the new location of the file/folder being renamed.
+   */
+  public void setNewUri(@NonNull final String newUri) {
+    this.newUri = Preconditions.checkNotNull(newUri, "newUri");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("oldUri", this.oldUri);
+    b.add("newUri", this.newUri);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    FileRename other = (FileRename) obj;
+    if (this.oldUri == null) {
+      if (other.oldUri != null)
+        return false;
+    } else if (!this.oldUri.equals(other.oldUri))
+      return false;
+    if (this.newUri == null) {
+      if (other.newUri != null)
+        return false;
+    } else if (!this.newUri.equals(other.newUri))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.oldUri== null) ? 0 : this.oldUri.hashCode());
+    return prime * result + ((this.newUri== null) ? 0 : this.newUri.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/FileSystemWatcher.java b/java/org/eclipse/lsp4j/FileSystemWatcher.java
new file mode 100644
index 0000000..cb09b12
--- /dev/null
+++ b/java/org/eclipse/lsp4j/FileSystemWatcher.java
@@ -0,0 +1,121 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class FileSystemWatcher {
+  /**
+   * The glob pattern to watch
+   */
+  @NonNull
+  private String globPattern;
+  
+  /**
+   * The kind of events of interest. If omitted it defaults
+   * to WatchKind.Create | WatchKind.Change | WatchKind.Delete
+   * which is 7.
+   */
+  private Integer kind;
+  
+  public FileSystemWatcher() {
+  }
+  
+  public FileSystemWatcher(@NonNull final String globPattern) {
+    this.globPattern = Preconditions.<String>checkNotNull(globPattern, "globPattern");
+  }
+  
+  public FileSystemWatcher(@NonNull final String globPattern, final Integer kind) {
+    this(globPattern);
+    this.kind = kind;
+  }
+  
+  /**
+   * The glob pattern to watch
+   */
+  @Pure
+  @NonNull
+  public String getGlobPattern() {
+    return this.globPattern;
+  }
+  
+  /**
+   * The glob pattern to watch
+   */
+  public void setGlobPattern(@NonNull final String globPattern) {
+    this.globPattern = Preconditions.checkNotNull(globPattern, "globPattern");
+  }
+  
+  /**
+   * The kind of events of interest. If omitted it defaults
+   * to WatchKind.Create | WatchKind.Change | WatchKind.Delete
+   * which is 7.
+   */
+  @Pure
+  public Integer getKind() {
+    return this.kind;
+  }
+  
+  /**
+   * The kind of events of interest. If omitted it defaults
+   * to WatchKind.Create | WatchKind.Change | WatchKind.Delete
+   * which is 7.
+   */
+  public void setKind(final Integer kind) {
+    this.kind = kind;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("globPattern", this.globPattern);
+    b.add("kind", this.kind);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    FileSystemWatcher other = (FileSystemWatcher) obj;
+    if (this.globPattern == null) {
+      if (other.globPattern != null)
+        return false;
+    } else if (!this.globPattern.equals(other.globPattern))
+      return false;
+    if (this.kind == null) {
+      if (other.kind != null)
+        return false;
+    } else if (!this.kind.equals(other.kind))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.globPattern== null) ? 0 : this.globPattern.hashCode());
+    return prime * result + ((this.kind== null) ? 0 : this.kind.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/FoldingRange.java b/java/org/eclipse/lsp4j/FoldingRange.java
new file mode 100644
index 0000000..488ddb5
--- /dev/null
+++ b/java/org/eclipse/lsp4j/FoldingRange.java
@@ -0,0 +1,197 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Represents a folding range.
+ */
+@SuppressWarnings("all")
+public class FoldingRange {
+  /**
+   * The zero-based line number from where the folded range starts.
+   */
+  private int startLine;
+  
+  /**
+   * The zero-based line number where the folded range ends.
+   */
+  private int endLine;
+  
+  /**
+   * The zero-based character offset from where the folded range starts. If not defined, defaults
+   * to the length of the start line.
+   */
+  private Integer startCharacter;
+  
+  /**
+   * The zero-based character offset before the folded range ends. If not defined, defaults to the
+   * length of the end line.
+   */
+  private Integer endCharacter;
+  
+  /**
+   * Describes the kind of the folding range such as {@link FoldingRangeKind#Comment} or {@link FoldingRangeKind#Region}.
+   * The kind is used to categorize folding ranges and used by commands like 'Fold all comments'.
+   * See {@link FoldingRangeKind} for an enumeration of standardized kinds.
+   */
+  private String kind;
+  
+  public FoldingRange() {
+  }
+  
+  public FoldingRange(final int startLine, final int endLine) {
+    this.startLine = startLine;
+    this.endLine = endLine;
+  }
+  
+  /**
+   * The zero-based line number from where the folded range starts.
+   */
+  @Pure
+  public int getStartLine() {
+    return this.startLine;
+  }
+  
+  /**
+   * The zero-based line number from where the folded range starts.
+   */
+  public void setStartLine(final int startLine) {
+    this.startLine = startLine;
+  }
+  
+  /**
+   * The zero-based line number where the folded range ends.
+   */
+  @Pure
+  public int getEndLine() {
+    return this.endLine;
+  }
+  
+  /**
+   * The zero-based line number where the folded range ends.
+   */
+  public void setEndLine(final int endLine) {
+    this.endLine = endLine;
+  }
+  
+  /**
+   * The zero-based character offset from where the folded range starts. If not defined, defaults
+   * to the length of the start line.
+   */
+  @Pure
+  public Integer getStartCharacter() {
+    return this.startCharacter;
+  }
+  
+  /**
+   * The zero-based character offset from where the folded range starts. If not defined, defaults
+   * to the length of the start line.
+   */
+  public void setStartCharacter(final Integer startCharacter) {
+    this.startCharacter = startCharacter;
+  }
+  
+  /**
+   * The zero-based character offset before the folded range ends. If not defined, defaults to the
+   * length of the end line.
+   */
+  @Pure
+  public Integer getEndCharacter() {
+    return this.endCharacter;
+  }
+  
+  /**
+   * The zero-based character offset before the folded range ends. If not defined, defaults to the
+   * length of the end line.
+   */
+  public void setEndCharacter(final Integer endCharacter) {
+    this.endCharacter = endCharacter;
+  }
+  
+  /**
+   * Describes the kind of the folding range such as {@link FoldingRangeKind#Comment} or {@link FoldingRangeKind#Region}.
+   * The kind is used to categorize folding ranges and used by commands like 'Fold all comments'.
+   * See {@link FoldingRangeKind} for an enumeration of standardized kinds.
+   */
+  @Pure
+  public String getKind() {
+    return this.kind;
+  }
+  
+  /**
+   * Describes the kind of the folding range such as {@link FoldingRangeKind#Comment} or {@link FoldingRangeKind#Region}.
+   * The kind is used to categorize folding ranges and used by commands like 'Fold all comments'.
+   * See {@link FoldingRangeKind} for an enumeration of standardized kinds.
+   */
+  public void setKind(final String kind) {
+    this.kind = kind;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("startLine", this.startLine);
+    b.add("endLine", this.endLine);
+    b.add("startCharacter", this.startCharacter);
+    b.add("endCharacter", this.endCharacter);
+    b.add("kind", this.kind);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    FoldingRange other = (FoldingRange) obj;
+    if (other.startLine != this.startLine)
+      return false;
+    if (other.endLine != this.endLine)
+      return false;
+    if (this.startCharacter == null) {
+      if (other.startCharacter != null)
+        return false;
+    } else if (!this.startCharacter.equals(other.startCharacter))
+      return false;
+    if (this.endCharacter == null) {
+      if (other.endCharacter != null)
+        return false;
+    } else if (!this.endCharacter.equals(other.endCharacter))
+      return false;
+    if (this.kind == null) {
+      if (other.kind != null)
+        return false;
+    } else if (!this.kind.equals(other.kind))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + this.startLine;
+    result = prime * result + this.endLine;
+    result = prime * result + ((this.startCharacter== null) ? 0 : this.startCharacter.hashCode());
+    result = prime * result + ((this.endCharacter== null) ? 0 : this.endCharacter.hashCode());
+    return prime * result + ((this.kind== null) ? 0 : this.kind.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/FoldingRangeCapabilities.java b/java/org/eclipse/lsp4j/FoldingRangeCapabilities.java
new file mode 100644
index 0000000..034cedb
--- /dev/null
+++ b/java/org/eclipse/lsp4j/FoldingRangeCapabilities.java
@@ -0,0 +1,114 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to `textDocument/foldingRange` requests.
+ * <p>
+ * Since 3.10.0
+ */
+@SuppressWarnings("all")
+public class FoldingRangeCapabilities extends DynamicRegistrationCapabilities {
+  /**
+   * The maximum number of folding ranges that the client prefers to receive per document. The value serves as a
+   * hint, servers are free to follow the limit.
+   */
+  private Integer rangeLimit;
+  
+  /**
+   * If set, the client signals that it only supports folding complete lines. If set, client will
+   * ignore specified {@link FoldingRange#startCharacter} and {@link FoldingRange#endCharacter} properties.
+   */
+  private Boolean lineFoldingOnly;
+  
+  /**
+   * The maximum number of folding ranges that the client prefers to receive per document. The value serves as a
+   * hint, servers are free to follow the limit.
+   */
+  @Pure
+  public Integer getRangeLimit() {
+    return this.rangeLimit;
+  }
+  
+  /**
+   * The maximum number of folding ranges that the client prefers to receive per document. The value serves as a
+   * hint, servers are free to follow the limit.
+   */
+  public void setRangeLimit(final Integer rangeLimit) {
+    this.rangeLimit = rangeLimit;
+  }
+  
+  /**
+   * If set, the client signals that it only supports folding complete lines. If set, client will
+   * ignore specified {@link FoldingRange#startCharacter} and {@link FoldingRange#endCharacter} properties.
+   */
+  @Pure
+  public Boolean getLineFoldingOnly() {
+    return this.lineFoldingOnly;
+  }
+  
+  /**
+   * If set, the client signals that it only supports folding complete lines. If set, client will
+   * ignore specified {@link FoldingRange#startCharacter} and {@link FoldingRange#endCharacter} properties.
+   */
+  public void setLineFoldingOnly(final Boolean lineFoldingOnly) {
+    this.lineFoldingOnly = lineFoldingOnly;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("rangeLimit", this.rangeLimit);
+    b.add("lineFoldingOnly", this.lineFoldingOnly);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    FoldingRangeCapabilities other = (FoldingRangeCapabilities) obj;
+    if (this.rangeLimit == null) {
+      if (other.rangeLimit != null)
+        return false;
+    } else if (!this.rangeLimit.equals(other.rangeLimit))
+      return false;
+    if (this.lineFoldingOnly == null) {
+      if (other.lineFoldingOnly != null)
+        return false;
+    } else if (!this.lineFoldingOnly.equals(other.lineFoldingOnly))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.rangeLimit== null) ? 0 : this.rangeLimit.hashCode());
+    return prime * result + ((this.lineFoldingOnly== null) ? 0 : this.lineFoldingOnly.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/FoldingRangeKind.java b/java/org/eclipse/lsp4j/FoldingRangeKind.java
new file mode 100644
index 0000000..1838c38
--- /dev/null
+++ b/java/org/eclipse/lsp4j/FoldingRangeKind.java
@@ -0,0 +1,35 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j;
+
+/**
+ * Enum of known range kinds
+ */
+public final class FoldingRangeKind {
+	private FoldingRangeKind() {}
+	
+	/**
+	 * Folding range for a comment
+	 */
+	public static final String Comment = "comment";
+	
+	/**
+	 * Folding range for a imports or includes
+	 */
+	public static final String Imports = "imports";
+	
+	/**
+	 * Folding range for a region (e.g. `#region`)
+	 */
+	public static final String Region = "region";
+
+}
diff --git a/java/org/eclipse/lsp4j/FoldingRangeProviderOptions.java b/java/org/eclipse/lsp4j/FoldingRangeProviderOptions.java
new file mode 100644
index 0000000..14ce226
--- /dev/null
+++ b/java/org/eclipse/lsp4j/FoldingRangeProviderOptions.java
@@ -0,0 +1,88 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractTextDocumentRegistrationAndWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Folding range options.
+ */
+@SuppressWarnings("all")
+public class FoldingRangeProviderOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  private String id;
+  
+  public FoldingRangeProviderOptions() {
+  }
+  
+  public FoldingRangeProviderOptions(final String id) {
+    this.id = id;
+  }
+  
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  @Pure
+  public String getId() {
+    return this.id;
+  }
+  
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  public void setId(final String id) {
+    this.id = id;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("id", this.id);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    FoldingRangeProviderOptions other = (FoldingRangeProviderOptions) obj;
+    if (this.id == null) {
+      if (other.id != null)
+        return false;
+    } else if (!this.id.equals(other.id))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.id== null) ? 0 : this.id.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/FoldingRangeRequestParams.java b/java/org/eclipse/lsp4j/FoldingRangeRequestParams.java
new file mode 100644
index 0000000..263854e
--- /dev/null
+++ b/java/org/eclipse/lsp4j/FoldingRangeRequestParams.java
@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.WorkDoneProgressAndPartialResultParams;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The folding range request is sent from the client to the server to return all folding
+ * ranges found in a given text document.
+ */
+@SuppressWarnings("all")
+public class FoldingRangeRequestParams extends WorkDoneProgressAndPartialResultParams {
+  /**
+   * The text document.
+   */
+  @NonNull
+  private TextDocumentIdentifier textDocument;
+  
+  public FoldingRangeRequestParams() {
+  }
+  
+  public FoldingRangeRequestParams(@NonNull final TextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.<TextDocumentIdentifier>checkNotNull(textDocument, "textDocument");
+  }
+  
+  /**
+   * The text document.
+   */
+  @Pure
+  @NonNull
+  public TextDocumentIdentifier getTextDocument() {
+    return this.textDocument;
+  }
+  
+  /**
+   * The text document.
+   */
+  public void setTextDocument(@NonNull final TextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.checkNotNull(textDocument, "textDocument");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("textDocument", this.textDocument);
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("partialResultToken", getPartialResultToken());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    FoldingRangeRequestParams other = (FoldingRangeRequestParams) obj;
+    if (this.textDocument == null) {
+      if (other.textDocument != null)
+        return false;
+    } else if (!this.textDocument.equals(other.textDocument))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.textDocument== null) ? 0 : this.textDocument.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/FormattingCapabilities.java b/java/org/eclipse/lsp4j/FormattingCapabilities.java
new file mode 100644
index 0000000..852dcbe
--- /dev/null
+++ b/java/org/eclipse/lsp4j/FormattingCapabilities.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the `textDocument/formatting`
+ */
+@SuppressWarnings("all")
+public class FormattingCapabilities extends DynamicRegistrationCapabilities {
+  public FormattingCapabilities() {
+  }
+  
+  public FormattingCapabilities(final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/FormattingOptions.java b/java/org/eclipse/lsp4j/FormattingOptions.java
new file mode 100644
index 0000000..cf4dd89
--- /dev/null
+++ b/java/org/eclipse/lsp4j/FormattingOptions.java
@@ -0,0 +1,230 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+import org.eclipse.lsp4j.jsonrpc.messages.Either3;
+import org.eclipse.xtext.xbase.lib.CollectionLiterals;
+
+/**
+ * Value-object describing what options formatting should use.
+ */
+@SuppressWarnings("all")
+public class FormattingOptions extends LinkedHashMap<String, Either3<String, Number, Boolean>> {
+  private static final String TAB_SIZE = "tabSize";
+  
+  private static final String INSERT_SPACES = "insertSpaces";
+  
+  private static final String TRIM_TRAILING_WHITESPACE = "trimTrailingWhitespace";
+  
+  private static final String INSERT_FINAL_NEWLINE = "insertFinalNewline";
+  
+  private static final String TRIM_FINAL_NEWLINES = "trimFinalNewlines";
+  
+  public FormattingOptions() {
+  }
+  
+  public FormattingOptions(final int tabSize, final boolean insertSpaces) {
+    this.setTabSize(tabSize);
+    this.setInsertSpaces(insertSpaces);
+  }
+  
+  /**
+   * @deprecated See https://github.com/eclipse/lsp4j/issues/99
+   */
+  @Deprecated
+  public FormattingOptions(final int tabSize, final boolean insertSpaces, final Map<String, String> properties) {
+    this(tabSize, insertSpaces);
+    this.setProperties(properties);
+  }
+  
+  public String getString(final String key) {
+    Either3<String, Number, Boolean> _get = this.get(key);
+    String _first = null;
+    if (_get!=null) {
+      _first=_get.getFirst();
+    }
+    return _first;
+  }
+  
+  public void putString(final String key, final String value) {
+    this.put(key, Either3.<String, Number, Boolean>forFirst(value));
+  }
+  
+  public Number getNumber(final String key) {
+    Either3<String, Number, Boolean> _get = this.get(key);
+    Number _second = null;
+    if (_get!=null) {
+      _second=_get.getSecond();
+    }
+    return _second;
+  }
+  
+  public void putNumber(final String key, final Number value) {
+    this.put(key, Either3.<String, Number, Boolean>forSecond(value));
+  }
+  
+  public Boolean getBoolean(final String key) {
+    Either3<String, Number, Boolean> _get = this.get(key);
+    Boolean _third = null;
+    if (_get!=null) {
+      _third=_get.getThird();
+    }
+    return _third;
+  }
+  
+  public void putBoolean(final String key, final Boolean value) {
+    this.put(key, Either3.<String, Number, Boolean>forThird(value));
+  }
+  
+  /**
+   * Size of a tab in spaces.
+   */
+  public int getTabSize() {
+    final Number value = this.getNumber(FormattingOptions.TAB_SIZE);
+    if ((value != null)) {
+      return value.intValue();
+    } else {
+      return 0;
+    }
+  }
+  
+  public void setTabSize(final int tabSize) {
+    this.putNumber(FormattingOptions.TAB_SIZE, Integer.valueOf(tabSize));
+  }
+  
+  /**
+   * Prefer spaces over tabs.
+   */
+  public boolean isInsertSpaces() {
+    final Boolean value = this.getBoolean(FormattingOptions.INSERT_SPACES);
+    if ((value != null)) {
+      return (value).booleanValue();
+    } else {
+      return false;
+    }
+  }
+  
+  public void setInsertSpaces(final boolean insertSpaces) {
+    this.putBoolean(FormattingOptions.INSERT_SPACES, Boolean.valueOf(insertSpaces));
+  }
+  
+  /**
+   * Trim trailing whitespace on a line.
+   * <p>
+   * Since 3.15.0
+   */
+  public boolean isTrimTrailingWhitespace() {
+    final Boolean value = this.getBoolean(FormattingOptions.TRIM_TRAILING_WHITESPACE);
+    if ((value != null)) {
+      return (value).booleanValue();
+    } else {
+      return false;
+    }
+  }
+  
+  public void setTrimTrailingWhitespace(final boolean trimTrailingWhitespace) {
+    this.putBoolean(FormattingOptions.TRIM_TRAILING_WHITESPACE, Boolean.valueOf(trimTrailingWhitespace));
+  }
+  
+  /**
+   * Insert a newline character at the end of the file if one does not exist.
+   * <p>
+   * Since 3.15.0
+   */
+  public boolean isInsertFinalNewline() {
+    final Boolean value = this.getBoolean(FormattingOptions.INSERT_FINAL_NEWLINE);
+    if ((value != null)) {
+      return (value).booleanValue();
+    } else {
+      return false;
+    }
+  }
+  
+  public void setInsertFinalNewline(final boolean insertFinalNewline) {
+    this.putBoolean(FormattingOptions.INSERT_FINAL_NEWLINE, Boolean.valueOf(insertFinalNewline));
+  }
+  
+  /**
+   * Trim all newlines after the final newline at the end of the file.
+   * <p>
+   * Since 3.15.0
+   */
+  public boolean isTrimFinalNewlines() {
+    final Boolean value = this.getBoolean(FormattingOptions.TRIM_FINAL_NEWLINES);
+    if ((value != null)) {
+      return (value).booleanValue();
+    } else {
+      return false;
+    }
+  }
+  
+  public void setTrimFinalNewlines(final boolean trimFinalNewlines) {
+    this.putBoolean(FormattingOptions.TRIM_FINAL_NEWLINES, Boolean.valueOf(trimFinalNewlines));
+  }
+  
+  /**
+   * @deprecated See https://github.com/eclipse/lsp4j/issues/99
+   */
+  @Deprecated
+  public Map<String, String> getProperties() {
+    final LinkedHashMap<String, String> properties = CollectionLiterals.<String, String>newLinkedHashMap();
+    Set<Map.Entry<String, Either3<String, Number, Boolean>>> _entrySet = this.entrySet();
+    for (final Map.Entry<String, Either3<String, Number, Boolean>> entry : _entrySet) {
+      {
+        Serializable _switchResult = null;
+        Either3<String, Number, Boolean> _value = entry.getValue();
+        final Either3<String, Number, Boolean> it = _value;
+        boolean _matched = false;
+        boolean _isFirst = it.isFirst();
+        if (_isFirst) {
+          _matched=true;
+          _switchResult = it.getFirst();
+        }
+        if (!_matched) {
+          boolean _isSecond = it.isSecond();
+          if (_isSecond) {
+            _matched=true;
+            _switchResult = it.getSecond();
+          }
+        }
+        if (!_matched) {
+          boolean _isThird = it.isThird();
+          if (_isThird) {
+            _matched=true;
+            _switchResult = it.getThird();
+          }
+        }
+        final Serializable value = _switchResult;
+        if ((value != null)) {
+          properties.put(entry.getKey(), value.toString());
+        }
+      }
+    }
+    return Collections.<String, String>unmodifiableMap(properties);
+  }
+  
+  /**
+   * @deprecated See https://github.com/eclipse/lsp4j/issues/99
+   */
+  @Deprecated
+  public void setProperties(final Map<String, String> properties) {
+    Set<Map.Entry<String, String>> _entrySet = properties.entrySet();
+    for (final Map.Entry<String, String> entry : _entrySet) {
+      this.putString(entry.getKey(), entry.getValue());
+    }
+  }
+}
diff --git a/java/org/eclipse/lsp4j/GeneralClientCapabilities.java b/java/org/eclipse/lsp4j/GeneralClientCapabilities.java
new file mode 100644
index 0000000..6607b77
--- /dev/null
+++ b/java/org/eclipse/lsp4j/GeneralClientCapabilities.java
@@ -0,0 +1,118 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.MarkdownCapabilities;
+import org.eclipse.lsp4j.RegularExpressionsCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * General client capabilities.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class GeneralClientCapabilities {
+  /**
+   * Client capabilities specific to regular expressions.
+   * <p>
+   * Since 3.16.0
+   */
+  private RegularExpressionsCapabilities regularExpressions;
+  
+  /**
+   * Client capabilities specific to the client's markdown parser.
+   * <p>
+   * Since 3.16.0
+   */
+  private MarkdownCapabilities markdown;
+  
+  /**
+   * Client capabilities specific to regular expressions.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public RegularExpressionsCapabilities getRegularExpressions() {
+    return this.regularExpressions;
+  }
+  
+  /**
+   * Client capabilities specific to regular expressions.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setRegularExpressions(final RegularExpressionsCapabilities regularExpressions) {
+    this.regularExpressions = regularExpressions;
+  }
+  
+  /**
+   * Client capabilities specific to the client's markdown parser.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public MarkdownCapabilities getMarkdown() {
+    return this.markdown;
+  }
+  
+  /**
+   * Client capabilities specific to the client's markdown parser.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setMarkdown(final MarkdownCapabilities markdown) {
+    this.markdown = markdown;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("regularExpressions", this.regularExpressions);
+    b.add("markdown", this.markdown);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    GeneralClientCapabilities other = (GeneralClientCapabilities) obj;
+    if (this.regularExpressions == null) {
+      if (other.regularExpressions != null)
+        return false;
+    } else if (!this.regularExpressions.equals(other.regularExpressions))
+      return false;
+    if (this.markdown == null) {
+      if (other.markdown != null)
+        return false;
+    } else if (!this.markdown.equals(other.markdown))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.regularExpressions== null) ? 0 : this.regularExpressions.hashCode());
+    return prime * result + ((this.markdown== null) ? 0 : this.markdown.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/Hover.java b/java/org/eclipse/lsp4j/Hover.java
new file mode 100644
index 0000000..9495481
--- /dev/null
+++ b/java/org/eclipse/lsp4j/Hover.java
@@ -0,0 +1,158 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import com.google.gson.annotations.JsonAdapter;
+import java.util.Arrays;
+import java.util.List;
+import org.eclipse.lsp4j.MarkedString;
+import org.eclipse.lsp4j.MarkupContent;
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.adapters.HoverTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The result of a hover request.
+ */
+@JsonAdapter(HoverTypeAdapter.Factory.class)
+@SuppressWarnings("all")
+public class Hover {
+  /**
+   * The hover's content as markdown
+   */
+  @NonNull
+  private Either<List<Either<String, MarkedString>>, MarkupContent> contents;
+  
+  /**
+   * An optional range
+   */
+  private Range range;
+  
+  public Hover() {
+  }
+  
+  public Hover(@NonNull final List<Either<String, MarkedString>> contents) {
+    this.setContents(Preconditions.<List<Either<String, MarkedString>>>checkNotNull(contents, "contents"));
+  }
+  
+  public Hover(@NonNull final List<Either<String, MarkedString>> contents, final Range range) {
+    this.setContents(Preconditions.<List<Either<String, MarkedString>>>checkNotNull(contents, "contents"));
+    this.range = range;
+  }
+  
+  public Hover(@NonNull final MarkupContent contents) {
+    this.setContents(Preconditions.<MarkupContent>checkNotNull(contents, "contents"));
+  }
+  
+  public Hover(@NonNull final MarkupContent contents, final Range range) {
+    this.setContents(Preconditions.<MarkupContent>checkNotNull(contents, "contents"));
+    this.range = range;
+  }
+  
+  public Hover(@NonNull final Either<String, MarkedString> contents) {
+    this.setContents(Arrays.<Either<String, MarkedString>>asList(Preconditions.<Either<String, MarkedString>>checkNotNull(contents, "contents")));
+  }
+  
+  /**
+   * The hover's content as markdown
+   */
+  @Pure
+  @NonNull
+  public Either<List<Either<String, MarkedString>>, MarkupContent> getContents() {
+    return this.contents;
+  }
+  
+  /**
+   * The hover's content as markdown
+   */
+  public void setContents(@NonNull final Either<List<Either<String, MarkedString>>, MarkupContent> contents) {
+    this.contents = Preconditions.checkNotNull(contents, "contents");
+  }
+  
+  public void setContents(final List<Either<String, MarkedString>> contents) {
+    if (contents == null) {
+      Preconditions.checkNotNull(contents, "contents");
+      this.contents = null;
+      return;
+    }
+    this.contents = Either.forLeft(contents);
+  }
+  
+  public void setContents(final MarkupContent contents) {
+    if (contents == null) {
+      Preconditions.checkNotNull(contents, "contents");
+      this.contents = null;
+      return;
+    }
+    this.contents = Either.forRight(contents);
+  }
+  
+  /**
+   * An optional range
+   */
+  @Pure
+  public Range getRange() {
+    return this.range;
+  }
+  
+  /**
+   * An optional range
+   */
+  public void setRange(final Range range) {
+    this.range = range;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("contents", this.contents);
+    b.add("range", this.range);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    Hover other = (Hover) obj;
+    if (this.contents == null) {
+      if (other.contents != null)
+        return false;
+    } else if (!this.contents.equals(other.contents))
+      return false;
+    if (this.range == null) {
+      if (other.range != null)
+        return false;
+    } else if (!this.range.equals(other.range))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.contents== null) ? 0 : this.contents.hashCode());
+    return prime * result + ((this.range== null) ? 0 : this.range.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/HoverCapabilities.java b/java/org/eclipse/lsp4j/HoverCapabilities.java
new file mode 100644
index 0000000..423ff5e
--- /dev/null
+++ b/java/org/eclipse/lsp4j/HoverCapabilities.java
@@ -0,0 +1,102 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the `textDocument/hover`
+ */
+@SuppressWarnings("all")
+public class HoverCapabilities extends DynamicRegistrationCapabilities {
+  /**
+   * Client supports the following content formats if the content
+   * property refers to {@link MarkupContent}.
+   * The order describes the preferred format of the client.
+   * <p>
+   * See {@link MarkupKind} for allowed values.
+   */
+  private List<String> contentFormat;
+  
+  public HoverCapabilities() {
+  }
+  
+  public HoverCapabilities(final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+  }
+  
+  public HoverCapabilities(final List<String> contentFormat, final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+    this.contentFormat = contentFormat;
+  }
+  
+  /**
+   * Client supports the following content formats if the content
+   * property refers to {@link MarkupContent}.
+   * The order describes the preferred format of the client.
+   * <p>
+   * See {@link MarkupKind} for allowed values.
+   */
+  @Pure
+  public List<String> getContentFormat() {
+    return this.contentFormat;
+  }
+  
+  /**
+   * Client supports the following content formats if the content
+   * property refers to {@link MarkupContent}.
+   * The order describes the preferred format of the client.
+   * <p>
+   * See {@link MarkupKind} for allowed values.
+   */
+  public void setContentFormat(final List<String> contentFormat) {
+    this.contentFormat = contentFormat;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("contentFormat", this.contentFormat);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    HoverCapabilities other = (HoverCapabilities) obj;
+    if (this.contentFormat == null) {
+      if (other.contentFormat != null)
+        return false;
+    } else if (!this.contentFormat.equals(other.contentFormat))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.contentFormat== null) ? 0 : this.contentFormat.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/HoverOptions.java b/java/org/eclipse/lsp4j/HoverOptions.java
new file mode 100644
index 0000000..f6596bd
--- /dev/null
+++ b/java/org/eclipse/lsp4j/HoverOptions.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Hover options.
+ */
+@SuppressWarnings("all")
+public class HoverOptions extends AbstractWorkDoneProgressOptions {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/HoverParams.java b/java/org/eclipse/lsp4j/HoverParams.java
new file mode 100644
index 0000000..d4d9a3c
--- /dev/null
+++ b/java/org/eclipse/lsp4j/HoverParams.java
@@ -0,0 +1,64 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.Position;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.TextDocumentPositionAndWorkDoneProgressParams;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The hover request is sent from the client to the server to request hover information at a given
+ * text document position.
+ */
+@SuppressWarnings("all")
+public class HoverParams extends TextDocumentPositionAndWorkDoneProgressParams {
+  public HoverParams() {
+  }
+  
+  public HoverParams(@NonNull final TextDocumentIdentifier textDocument, @NonNull final Position position) {
+    super(textDocument, position);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("textDocument", getTextDocument());
+    b.add("uri", getUri());
+    b.add("position", getPosition());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/HoverRegistrationOptions.java b/java/org/eclipse/lsp4j/HoverRegistrationOptions.java
new file mode 100644
index 0000000..31c25a5
--- /dev/null
+++ b/java/org/eclipse/lsp4j/HoverRegistrationOptions.java
@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractTextDocumentRegistrationAndWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Hover registration options.
+ */
+@SuppressWarnings("all")
+public class HoverRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ImplementationCapabilities.java b/java/org/eclipse/lsp4j/ImplementationCapabilities.java
new file mode 100644
index 0000000..38791a7
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ImplementationCapabilities.java
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the `textDocument/implementation`.
+ * <p>
+ * Since 3.6.0
+ */
+@SuppressWarnings("all")
+public class ImplementationCapabilities extends DynamicRegistrationCapabilities {
+  /**
+   * The client supports additional metadata in the form of definition links.
+   * <p>
+   * Since 3.14.0
+   */
+  private Boolean linkSupport;
+  
+  public ImplementationCapabilities() {
+  }
+  
+  public ImplementationCapabilities(final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+  }
+  
+  public ImplementationCapabilities(final Boolean dynamicRegistration, final Boolean linkSupport) {
+    super(dynamicRegistration);
+    this.linkSupport = linkSupport;
+  }
+  
+  /**
+   * The client supports additional metadata in the form of definition links.
+   * <p>
+   * Since 3.14.0
+   */
+  @Pure
+  public Boolean getLinkSupport() {
+    return this.linkSupport;
+  }
+  
+  /**
+   * The client supports additional metadata in the form of definition links.
+   * <p>
+   * Since 3.14.0
+   */
+  public void setLinkSupport(final Boolean linkSupport) {
+    this.linkSupport = linkSupport;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("linkSupport", this.linkSupport);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    ImplementationCapabilities other = (ImplementationCapabilities) obj;
+    if (this.linkSupport == null) {
+      if (other.linkSupport != null)
+        return false;
+    } else if (!this.linkSupport.equals(other.linkSupport))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.linkSupport== null) ? 0 : this.linkSupport.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ImplementationOptions.java b/java/org/eclipse/lsp4j/ImplementationOptions.java
new file mode 100644
index 0000000..b0245ac
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ImplementationOptions.java
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class ImplementationOptions extends AbstractWorkDoneProgressOptions {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ImplementationParams.java b/java/org/eclipse/lsp4j/ImplementationParams.java
new file mode 100644
index 0000000..7241d23
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ImplementationParams.java
@@ -0,0 +1,65 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.Position;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.TextDocumentPositionAndWorkDoneProgressAndPartialResultParams;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The go to implementation request is sent from the client to the server to resolve the implementation
+ * location of a symbol at a given text document position.
+ */
+@SuppressWarnings("all")
+public class ImplementationParams extends TextDocumentPositionAndWorkDoneProgressAndPartialResultParams {
+  public ImplementationParams() {
+  }
+  
+  public ImplementationParams(@NonNull final TextDocumentIdentifier textDocument, @NonNull final Position position) {
+    super(textDocument, position);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("partialResultToken", getPartialResultToken());
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("textDocument", getTextDocument());
+    b.add("uri", getUri());
+    b.add("position", getPosition());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ImplementationRegistrationOptions.java b/java/org/eclipse/lsp4j/ImplementationRegistrationOptions.java
new file mode 100644
index 0000000..8d026a2
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ImplementationRegistrationOptions.java
@@ -0,0 +1,85 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractTextDocumentRegistrationAndWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class ImplementationRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  private String id;
+  
+  public ImplementationRegistrationOptions() {
+  }
+  
+  public ImplementationRegistrationOptions(final String id) {
+    this.id = id;
+  }
+  
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  @Pure
+  public String getId() {
+    return this.id;
+  }
+  
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  public void setId(final String id) {
+    this.id = id;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("id", this.id);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    ImplementationRegistrationOptions other = (ImplementationRegistrationOptions) obj;
+    if (this.id == null) {
+      if (other.id != null)
+        return false;
+    } else if (!this.id.equals(other.id))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.id== null) ? 0 : this.id.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/InitializeError.java b/java/org/eclipse/lsp4j/InitializeError.java
new file mode 100644
index 0000000..dcd0f46
--- /dev/null
+++ b/java/org/eclipse/lsp4j/InitializeError.java
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class InitializeError {
+  /**
+   * Indicates whether the client executes the following retry logic:
+   * <ol>
+   * <li>Show the message provided by the ResponseError to the user.
+   * <li>User selects retry or cancel.
+   * <li>If user selected retry the initialize method is sent again.
+   * </ol>
+   */
+  private boolean retry;
+  
+  public InitializeError() {
+  }
+  
+  public InitializeError(final boolean retry) {
+    this.retry = retry;
+  }
+  
+  /**
+   * Indicates whether the client executes the following retry logic:
+   * <ol>
+   * <li>Show the message provided by the ResponseError to the user.
+   * <li>User selects retry or cancel.
+   * <li>If user selected retry the initialize method is sent again.
+   * </ol>
+   */
+  @Pure
+  public boolean isRetry() {
+    return this.retry;
+  }
+  
+  /**
+   * Indicates whether the client executes the following retry logic:
+   * <ol>
+   * <li>Show the message provided by the ResponseError to the user.
+   * <li>User selects retry or cancel.
+   * <li>If user selected retry the initialize method is sent again.
+   * </ol>
+   */
+  public void setRetry(final boolean retry) {
+    this.retry = retry;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("retry", this.retry);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    InitializeError other = (InitializeError) obj;
+    if (other.retry != this.retry)
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + (this.retry ? 1231 : 1237);
+  }
+}
diff --git a/java/org/eclipse/lsp4j/InitializeErrorCode.java b/java/org/eclipse/lsp4j/InitializeErrorCode.java
new file mode 100644
index 0000000..031c006
--- /dev/null
+++ b/java/org/eclipse/lsp4j/InitializeErrorCode.java
@@ -0,0 +1,27 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+/**
+ * Known error codes for an {@link InitializeError}
+ */
+@SuppressWarnings("all")
+public interface InitializeErrorCode {
+  /**
+   * If the protocol version provided by the client can't be handled by the server.
+   * 
+   * @deprecated This initialize error got replaced by client capabilities.
+   * There is no version handshake in version 3.0x
+   */
+  @Deprecated
+  static final int unknownProtocolVersion = 1;
+}
diff --git a/java/org/eclipse/lsp4j/InitializeParams.java b/java/org/eclipse/lsp4j/InitializeParams.java
new file mode 100644
index 0000000..5a55ee1
--- /dev/null
+++ b/java/org/eclipse/lsp4j/InitializeParams.java
@@ -0,0 +1,451 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import com.google.gson.annotations.JsonAdapter;
+import java.util.List;
+import org.eclipse.lsp4j.ClientCapabilities;
+import org.eclipse.lsp4j.ClientInfo;
+import org.eclipse.lsp4j.WorkDoneProgressParams;
+import org.eclipse.lsp4j.WorkspaceFolder;
+import org.eclipse.lsp4j.adapters.InitializeParamsTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The initialize request is sent as the first request from the client to the server.
+ */
+@JsonAdapter(InitializeParamsTypeAdapter.Factory.class)
+@SuppressWarnings("all")
+public class InitializeParams implements WorkDoneProgressParams {
+  /**
+   * An optional token that a server can use to report work done progress.
+   */
+  private Either<String, Integer> workDoneToken;
+  
+  /**
+   * The process Id of the parent process that started the server.
+   */
+  private Integer processId;
+  
+  /**
+   * The rootPath of the workspace. Is null if no folder is open.
+   * 
+   * @deprecated Use {@link #workspaceFolders} instead.
+   */
+  @Deprecated
+  private String rootPath;
+  
+  /**
+   * The rootUri of the workspace. Is null if no folder is open.
+   * If both {@link #rootPath} and `rootUri` are set, `rootUri` wins.
+   * 
+   * @deprecated Use {@link #workspaceFolders} instead.
+   */
+  @Deprecated
+  private String rootUri;
+  
+  /**
+   * User provided initialization options.
+   */
+  @JsonAdapter(JsonElementTypeAdapter.Factory.class)
+  private Object initializationOptions;
+  
+  /**
+   * The capabilities provided by the client (editor)
+   */
+  private ClientCapabilities capabilities;
+  
+  /**
+   * An optional extension to the protocol.
+   * To tell the server what client (editor) is talking to it.
+   * 
+   * @deprecated Use {@link #clientInfo} instead.
+   */
+  @Deprecated
+  private String clientName;
+  
+  /**
+   * Information about the client
+   * <p>
+   * Since 3.15.0
+   */
+  private ClientInfo clientInfo;
+  
+  /**
+   * The locale the client is currently showing the user interface
+   * in. This must not necessarily be the locale of the operating
+   * system.
+   * <p>
+   * Uses IETF language tags as the value's syntax
+   * (See https://en.wikipedia.org/wiki/IETF_language_tag)
+   * <p>
+   * Since 3.16.0
+   */
+  private String locale;
+  
+  /**
+   * The initial trace setting.
+   * For values, see {@link TraceValue}. If omitted trace is disabled ({@link TraceValue#Off}).
+   */
+  private String trace;
+  
+  /**
+   * The workspace folders configured in the client when the server starts.
+   * This property is only available if the client supports workspace folders.
+   * It can be `null` if the client supports workspace folders but none are
+   * configured.
+   * <p>
+   * Since 3.6.0
+   */
+  private List<WorkspaceFolder> workspaceFolders;
+  
+  /**
+   * An optional token that a server can use to report work done progress.
+   */
+  @Pure
+  @Override
+  public Either<String, Integer> getWorkDoneToken() {
+    return this.workDoneToken;
+  }
+  
+  /**
+   * An optional token that a server can use to report work done progress.
+   */
+  public void setWorkDoneToken(final Either<String, Integer> workDoneToken) {
+    this.workDoneToken = workDoneToken;
+  }
+  
+  public void setWorkDoneToken(final String workDoneToken) {
+    if (workDoneToken == null) {
+      this.workDoneToken = null;
+      return;
+    }
+    this.workDoneToken = Either.forLeft(workDoneToken);
+  }
+  
+  public void setWorkDoneToken(final Integer workDoneToken) {
+    if (workDoneToken == null) {
+      this.workDoneToken = null;
+      return;
+    }
+    this.workDoneToken = Either.forRight(workDoneToken);
+  }
+  
+  /**
+   * The process Id of the parent process that started the server.
+   */
+  @Pure
+  public Integer getProcessId() {
+    return this.processId;
+  }
+  
+  /**
+   * The process Id of the parent process that started the server.
+   */
+  public void setProcessId(final Integer processId) {
+    this.processId = processId;
+  }
+  
+  /**
+   * The rootPath of the workspace. Is null if no folder is open.
+   * 
+   * @deprecated Use {@link #workspaceFolders} instead.
+   */
+  @Pure
+  @Deprecated
+  public String getRootPath() {
+    return this.rootPath;
+  }
+  
+  /**
+   * The rootPath of the workspace. Is null if no folder is open.
+   * 
+   * @deprecated Use {@link #workspaceFolders} instead.
+   */
+  @Deprecated
+  public void setRootPath(final String rootPath) {
+    this.rootPath = rootPath;
+  }
+  
+  /**
+   * The rootUri of the workspace. Is null if no folder is open.
+   * If both {@link #rootPath} and `rootUri` are set, `rootUri` wins.
+   * 
+   * @deprecated Use {@link #workspaceFolders} instead.
+   */
+  @Pure
+  @Deprecated
+  public String getRootUri() {
+    return this.rootUri;
+  }
+  
+  /**
+   * The rootUri of the workspace. Is null if no folder is open.
+   * If both {@link #rootPath} and `rootUri` are set, `rootUri` wins.
+   * 
+   * @deprecated Use {@link #workspaceFolders} instead.
+   */
+  @Deprecated
+  public void setRootUri(final String rootUri) {
+    this.rootUri = rootUri;
+  }
+  
+  /**
+   * User provided initialization options.
+   */
+  @Pure
+  public Object getInitializationOptions() {
+    return this.initializationOptions;
+  }
+  
+  /**
+   * User provided initialization options.
+   */
+  public void setInitializationOptions(final Object initializationOptions) {
+    this.initializationOptions = initializationOptions;
+  }
+  
+  /**
+   * The capabilities provided by the client (editor)
+   */
+  @Pure
+  public ClientCapabilities getCapabilities() {
+    return this.capabilities;
+  }
+  
+  /**
+   * The capabilities provided by the client (editor)
+   */
+  public void setCapabilities(final ClientCapabilities capabilities) {
+    this.capabilities = capabilities;
+  }
+  
+  /**
+   * An optional extension to the protocol.
+   * To tell the server what client (editor) is talking to it.
+   * 
+   * @deprecated Use {@link #clientInfo} instead.
+   */
+  @Pure
+  @Deprecated
+  public String getClientName() {
+    return this.clientName;
+  }
+  
+  /**
+   * An optional extension to the protocol.
+   * To tell the server what client (editor) is talking to it.
+   * 
+   * @deprecated Use {@link #clientInfo} instead.
+   */
+  @Deprecated
+  public void setClientName(final String clientName) {
+    this.clientName = clientName;
+  }
+  
+  /**
+   * Information about the client
+   * <p>
+   * Since 3.15.0
+   */
+  @Pure
+  public ClientInfo getClientInfo() {
+    return this.clientInfo;
+  }
+  
+  /**
+   * Information about the client
+   * <p>
+   * Since 3.15.0
+   */
+  public void setClientInfo(final ClientInfo clientInfo) {
+    this.clientInfo = clientInfo;
+  }
+  
+  /**
+   * The locale the client is currently showing the user interface
+   * in. This must not necessarily be the locale of the operating
+   * system.
+   * <p>
+   * Uses IETF language tags as the value's syntax
+   * (See https://en.wikipedia.org/wiki/IETF_language_tag)
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public String getLocale() {
+    return this.locale;
+  }
+  
+  /**
+   * The locale the client is currently showing the user interface
+   * in. This must not necessarily be the locale of the operating
+   * system.
+   * <p>
+   * Uses IETF language tags as the value's syntax
+   * (See https://en.wikipedia.org/wiki/IETF_language_tag)
+   * <p>
+   * Since 3.16.0
+   */
+  public void setLocale(final String locale) {
+    this.locale = locale;
+  }
+  
+  /**
+   * The initial trace setting.
+   * For values, see {@link TraceValue}. If omitted trace is disabled ({@link TraceValue#Off}).
+   */
+  @Pure
+  public String getTrace() {
+    return this.trace;
+  }
+  
+  /**
+   * The initial trace setting.
+   * For values, see {@link TraceValue}. If omitted trace is disabled ({@link TraceValue#Off}).
+   */
+  public void setTrace(final String trace) {
+    this.trace = trace;
+  }
+  
+  /**
+   * The workspace folders configured in the client when the server starts.
+   * This property is only available if the client supports workspace folders.
+   * It can be `null` if the client supports workspace folders but none are
+   * configured.
+   * <p>
+   * Since 3.6.0
+   */
+  @Pure
+  public List<WorkspaceFolder> getWorkspaceFolders() {
+    return this.workspaceFolders;
+  }
+  
+  /**
+   * The workspace folders configured in the client when the server starts.
+   * This property is only available if the client supports workspace folders.
+   * It can be `null` if the client supports workspace folders but none are
+   * configured.
+   * <p>
+   * Since 3.6.0
+   */
+  public void setWorkspaceFolders(final List<WorkspaceFolder> workspaceFolders) {
+    this.workspaceFolders = workspaceFolders;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneToken", this.workDoneToken);
+    b.add("processId", this.processId);
+    b.add("rootPath", this.rootPath);
+    b.add("rootUri", this.rootUri);
+    b.add("initializationOptions", this.initializationOptions);
+    b.add("capabilities", this.capabilities);
+    b.add("clientName", this.clientName);
+    b.add("clientInfo", this.clientInfo);
+    b.add("locale", this.locale);
+    b.add("trace", this.trace);
+    b.add("workspaceFolders", this.workspaceFolders);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    InitializeParams other = (InitializeParams) obj;
+    if (this.workDoneToken == null) {
+      if (other.workDoneToken != null)
+        return false;
+    } else if (!this.workDoneToken.equals(other.workDoneToken))
+      return false;
+    if (this.processId == null) {
+      if (other.processId != null)
+        return false;
+    } else if (!this.processId.equals(other.processId))
+      return false;
+    if (this.rootPath == null) {
+      if (other.rootPath != null)
+        return false;
+    } else if (!this.rootPath.equals(other.rootPath))
+      return false;
+    if (this.rootUri == null) {
+      if (other.rootUri != null)
+        return false;
+    } else if (!this.rootUri.equals(other.rootUri))
+      return false;
+    if (this.initializationOptions == null) {
+      if (other.initializationOptions != null)
+        return false;
+    } else if (!this.initializationOptions.equals(other.initializationOptions))
+      return false;
+    if (this.capabilities == null) {
+      if (other.capabilities != null)
+        return false;
+    } else if (!this.capabilities.equals(other.capabilities))
+      return false;
+    if (this.clientName == null) {
+      if (other.clientName != null)
+        return false;
+    } else if (!this.clientName.equals(other.clientName))
+      return false;
+    if (this.clientInfo == null) {
+      if (other.clientInfo != null)
+        return false;
+    } else if (!this.clientInfo.equals(other.clientInfo))
+      return false;
+    if (this.locale == null) {
+      if (other.locale != null)
+        return false;
+    } else if (!this.locale.equals(other.locale))
+      return false;
+    if (this.trace == null) {
+      if (other.trace != null)
+        return false;
+    } else if (!this.trace.equals(other.trace))
+      return false;
+    if (this.workspaceFolders == null) {
+      if (other.workspaceFolders != null)
+        return false;
+    } else if (!this.workspaceFolders.equals(other.workspaceFolders))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.workDoneToken== null) ? 0 : this.workDoneToken.hashCode());
+    result = prime * result + ((this.processId== null) ? 0 : this.processId.hashCode());
+    result = prime * result + ((this.rootPath== null) ? 0 : this.rootPath.hashCode());
+    result = prime * result + ((this.rootUri== null) ? 0 : this.rootUri.hashCode());
+    result = prime * result + ((this.initializationOptions== null) ? 0 : this.initializationOptions.hashCode());
+    result = prime * result + ((this.capabilities== null) ? 0 : this.capabilities.hashCode());
+    result = prime * result + ((this.clientName== null) ? 0 : this.clientName.hashCode());
+    result = prime * result + ((this.clientInfo== null) ? 0 : this.clientInfo.hashCode());
+    result = prime * result + ((this.locale== null) ? 0 : this.locale.hashCode());
+    result = prime * result + ((this.trace== null) ? 0 : this.trace.hashCode());
+    return prime * result + ((this.workspaceFolders== null) ? 0 : this.workspaceFolders.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/InitializeResult.java b/java/org/eclipse/lsp4j/InitializeResult.java
new file mode 100644
index 0000000..a6e865c
--- /dev/null
+++ b/java/org/eclipse/lsp4j/InitializeResult.java
@@ -0,0 +1,123 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.ServerCapabilities;
+import org.eclipse.lsp4j.ServerInfo;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class InitializeResult {
+  /**
+   * The capabilities the language server provides.
+   */
+  @NonNull
+  private ServerCapabilities capabilities;
+  
+  /**
+   * Information about the server.
+   * <p>
+   * Since 3.15.0
+   */
+  private ServerInfo serverInfo;
+  
+  public InitializeResult() {
+  }
+  
+  public InitializeResult(@NonNull final ServerCapabilities capabilities) {
+    this.capabilities = Preconditions.<ServerCapabilities>checkNotNull(capabilities, "capabilities");
+  }
+  
+  public InitializeResult(@NonNull final ServerCapabilities capabilities, final ServerInfo serverInfo) {
+    this(capabilities);
+    this.serverInfo = serverInfo;
+  }
+  
+  /**
+   * The capabilities the language server provides.
+   */
+  @Pure
+  @NonNull
+  public ServerCapabilities getCapabilities() {
+    return this.capabilities;
+  }
+  
+  /**
+   * The capabilities the language server provides.
+   */
+  public void setCapabilities(@NonNull final ServerCapabilities capabilities) {
+    this.capabilities = Preconditions.checkNotNull(capabilities, "capabilities");
+  }
+  
+  /**
+   * Information about the server.
+   * <p>
+   * Since 3.15.0
+   */
+  @Pure
+  public ServerInfo getServerInfo() {
+    return this.serverInfo;
+  }
+  
+  /**
+   * Information about the server.
+   * <p>
+   * Since 3.15.0
+   */
+  public void setServerInfo(final ServerInfo serverInfo) {
+    this.serverInfo = serverInfo;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("capabilities", this.capabilities);
+    b.add("serverInfo", this.serverInfo);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    InitializeResult other = (InitializeResult) obj;
+    if (this.capabilities == null) {
+      if (other.capabilities != null)
+        return false;
+    } else if (!this.capabilities.equals(other.capabilities))
+      return false;
+    if (this.serverInfo == null) {
+      if (other.serverInfo != null)
+        return false;
+    } else if (!this.serverInfo.equals(other.serverInfo))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.capabilities== null) ? 0 : this.capabilities.hashCode());
+    return prime * result + ((this.serverInfo== null) ? 0 : this.serverInfo.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/InitializedParams.java b/java/org/eclipse/lsp4j/InitializedParams.java
new file mode 100644
index 0000000..923cd8e
--- /dev/null
+++ b/java/org/eclipse/lsp4j/InitializedParams.java
@@ -0,0 +1,43 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class InitializedParams {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 1;
+  }
+}
diff --git a/java/org/eclipse/lsp4j/InsertReplaceEdit.java b/java/org/eclipse/lsp4j/InsertReplaceEdit.java
new file mode 100644
index 0000000..799e247
--- /dev/null
+++ b/java/org/eclipse/lsp4j/InsertReplaceEdit.java
@@ -0,0 +1,149 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A special text edit to provide an insert and a replace operation.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class InsertReplaceEdit {
+  /**
+   * The string to be inserted.
+   */
+  @NonNull
+  private String newText;
+  
+  /**
+   * The range if the insert that is requested
+   */
+  @NonNull
+  private Range insert;
+  
+  /**
+   * The range if the replace that is requested.
+   */
+  @NonNull
+  private Range replace;
+  
+  public InsertReplaceEdit() {
+  }
+  
+  public InsertReplaceEdit(@NonNull final String newText, @NonNull final Range insert, @NonNull final Range replace) {
+    this.newText = Preconditions.<String>checkNotNull(newText, "newText");
+    this.insert = Preconditions.<Range>checkNotNull(insert, "insert");
+    this.replace = Preconditions.<Range>checkNotNull(replace, "replace");
+  }
+  
+  /**
+   * The string to be inserted.
+   */
+  @Pure
+  @NonNull
+  public String getNewText() {
+    return this.newText;
+  }
+  
+  /**
+   * The string to be inserted.
+   */
+  public void setNewText(@NonNull final String newText) {
+    this.newText = Preconditions.checkNotNull(newText, "newText");
+  }
+  
+  /**
+   * The range if the insert that is requested
+   */
+  @Pure
+  @NonNull
+  public Range getInsert() {
+    return this.insert;
+  }
+  
+  /**
+   * The range if the insert that is requested
+   */
+  public void setInsert(@NonNull final Range insert) {
+    this.insert = Preconditions.checkNotNull(insert, "insert");
+  }
+  
+  /**
+   * The range if the replace that is requested.
+   */
+  @Pure
+  @NonNull
+  public Range getReplace() {
+    return this.replace;
+  }
+  
+  /**
+   * The range if the replace that is requested.
+   */
+  public void setReplace(@NonNull final Range replace) {
+    this.replace = Preconditions.checkNotNull(replace, "replace");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("newText", this.newText);
+    b.add("insert", this.insert);
+    b.add("replace", this.replace);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    InsertReplaceEdit other = (InsertReplaceEdit) obj;
+    if (this.newText == null) {
+      if (other.newText != null)
+        return false;
+    } else if (!this.newText.equals(other.newText))
+      return false;
+    if (this.insert == null) {
+      if (other.insert != null)
+        return false;
+    } else if (!this.insert.equals(other.insert))
+      return false;
+    if (this.replace == null) {
+      if (other.replace != null)
+        return false;
+    } else if (!this.replace.equals(other.replace))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.newText== null) ? 0 : this.newText.hashCode());
+    result = prime * result + ((this.insert== null) ? 0 : this.insert.hashCode());
+    return prime * result + ((this.replace== null) ? 0 : this.replace.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/InsertTextFormat.java b/java/org/eclipse/lsp4j/InsertTextFormat.java
new file mode 100644
index 0000000..3849338
--- /dev/null
+++ b/java/org/eclipse/lsp4j/InsertTextFormat.java
@@ -0,0 +1,52 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j;
+
+/**
+ * Defines whether the insert text in a completion item should be interpreted as
+ * plain text or a snippet.
+ */
+public enum InsertTextFormat {
+	
+	/**
+	 * The primary text to be inserted is treated as a plain string.
+	 */
+	PlainText(1),
+	
+	/**
+	 * The primary text to be inserted is treated as a snippet.
+	 *
+	 * A snippet can define tab stops and placeholders with `$1`, `$2`
+	 * and `${3:foo}`. `$0` defines the final tab stop, it defaults to
+	 * the end of the snippet. Placeholders with equal identifiers are linked,
+	 * that is typing in one will update others too.
+	 */
+	Snippet(2);
+	
+	private final int value;
+	
+	InsertTextFormat(int value) {
+		this.value = value;
+	}
+	
+	public int getValue() {
+		return value;
+	}
+	
+	public static InsertTextFormat forValue(int value) {
+		InsertTextFormat[] allValues = InsertTextFormat.values();
+		if (value < 1 || value > allValues.length)
+			throw new IllegalArgumentException("Illegal enum value: " + value);
+		return allValues[value - 1];
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/InsertTextMode.java b/java/org/eclipse/lsp4j/InsertTextMode.java
new file mode 100644
index 0000000..0bd5384
--- /dev/null
+++ b/java/org/eclipse/lsp4j/InsertTextMode.java
@@ -0,0 +1,59 @@
+/******************************************************************************
+ * Copyright (c) 2020 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j;
+
+/**
+ * How whitespace and indentation is handled during completion
+ * item insertion.
+ *
+ * Since 3.16.0
+ */
+public enum InsertTextMode {
+	
+	/**
+	 * The insertion or replace strings is taken as it is. If the
+	 * value is multi line the lines below the cursor will be
+	 * inserted using the indentation defined in the string value.
+	 * The client will not apply any kind of adjustments to the
+	 * string.
+	 */
+	AsIs(1),
+	
+	/**
+	 * The editor adjusts leading whitespace of new lines so that
+	 * they match the indentation up to the cursor of the line for
+	 * which the item is accepted.
+	 *
+	 * Consider a line like this: [2tabs][cursor][3tabs]foo. Accepting a
+	 * multi line completion item is indented using 2 tabs and all
+	 * following lines inserted will be indented using 2 tabs as well.
+	 */
+	AdjustIndentation(2);
+	
+	private final int value;
+	
+	InsertTextMode(int value) {
+		this.value = value;
+	}
+	
+	public int getValue() {
+		return value;
+	}
+	
+	public static InsertTextMode forValue(int value) {
+		InsertTextMode[] allValues = InsertTextMode.values();
+		if (value < 1 || value > allValues.length)
+			throw new IllegalArgumentException("Illegal enum value: " + value);
+		return allValues[value - 1];
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/LinkedEditingRangeCapabilities.java b/java/org/eclipse/lsp4j/LinkedEditingRangeCapabilities.java
new file mode 100644
index 0000000..ca1ce59
--- /dev/null
+++ b/java/org/eclipse/lsp4j/LinkedEditingRangeCapabilities.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the {@code textDocument/linkedEditingRange} request.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class LinkedEditingRangeCapabilities extends DynamicRegistrationCapabilities {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/LinkedEditingRangeOptions.java b/java/org/eclipse/lsp4j/LinkedEditingRangeOptions.java
new file mode 100644
index 0000000..a3ecd4c
--- /dev/null
+++ b/java/org/eclipse/lsp4j/LinkedEditingRangeOptions.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Linked editing range options.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class LinkedEditingRangeOptions extends AbstractWorkDoneProgressOptions {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/LinkedEditingRangeParams.java b/java/org/eclipse/lsp4j/LinkedEditingRangeParams.java
new file mode 100644
index 0000000..70171f9
--- /dev/null
+++ b/java/org/eclipse/lsp4j/LinkedEditingRangeParams.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.TextDocumentPositionAndWorkDoneProgressParams;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The linked editing range request is sent from the client to the server to return for a given position
+ * in a document the range of the symbol at the position and all ranges that have the same content.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class LinkedEditingRangeParams extends TextDocumentPositionAndWorkDoneProgressParams {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("textDocument", getTextDocument());
+    b.add("uri", getUri());
+    b.add("position", getPosition());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/LinkedEditingRangeRegistrationOptions.java b/java/org/eclipse/lsp4j/LinkedEditingRangeRegistrationOptions.java
new file mode 100644
index 0000000..89b33c1
--- /dev/null
+++ b/java/org/eclipse/lsp4j/LinkedEditingRangeRegistrationOptions.java
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractTextDocumentRegistrationAndWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Linked editing range registration options.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class LinkedEditingRangeRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  private String id;
+  
+  public LinkedEditingRangeRegistrationOptions() {
+  }
+  
+  public LinkedEditingRangeRegistrationOptions(final String id) {
+    this.id = id;
+  }
+  
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  @Pure
+  public String getId() {
+    return this.id;
+  }
+  
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  public void setId(final String id) {
+    this.id = id;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("id", this.id);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    LinkedEditingRangeRegistrationOptions other = (LinkedEditingRangeRegistrationOptions) obj;
+    if (this.id == null) {
+      if (other.id != null)
+        return false;
+    } else if (!this.id.equals(other.id))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.id== null) ? 0 : this.id.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/LinkedEditingRanges.java b/java/org/eclipse/lsp4j/LinkedEditingRanges.java
new file mode 100644
index 0000000..61d478c
--- /dev/null
+++ b/java/org/eclipse/lsp4j/LinkedEditingRanges.java
@@ -0,0 +1,137 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The linked editing range response is sent from the server to the client to return the range of the symbol
+ * at the given position and all ranges that have the same content.
+ * <p>
+ * Optionally a word pattern can be returned to describe valid contents.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class LinkedEditingRanges {
+  /**
+   * A list of ranges that can be renamed together. The ranges must have
+   * identical length and contain identical text content. The ranges cannot overlap.
+   */
+  @NonNull
+  private List<Range> ranges;
+  
+  /**
+   * An optional word pattern (regular expression) that describes valid contents for
+   * the given ranges. If no pattern is provided, the client configuration's word
+   * pattern will be used.
+   */
+  private String wordPattern;
+  
+  public LinkedEditingRanges() {
+    ArrayList<Range> _arrayList = new ArrayList<Range>();
+    this.ranges = _arrayList;
+  }
+  
+  public LinkedEditingRanges(@NonNull final List<Range> ranges) {
+    this.ranges = Preconditions.<List<Range>>checkNotNull(ranges, "ranges");
+  }
+  
+  public LinkedEditingRanges(@NonNull final List<Range> ranges, final String wordPattern) {
+    this(ranges);
+    this.wordPattern = wordPattern;
+  }
+  
+  /**
+   * A list of ranges that can be renamed together. The ranges must have
+   * identical length and contain identical text content. The ranges cannot overlap.
+   */
+  @Pure
+  @NonNull
+  public List<Range> getRanges() {
+    return this.ranges;
+  }
+  
+  /**
+   * A list of ranges that can be renamed together. The ranges must have
+   * identical length and contain identical text content. The ranges cannot overlap.
+   */
+  public void setRanges(@NonNull final List<Range> ranges) {
+    this.ranges = Preconditions.checkNotNull(ranges, "ranges");
+  }
+  
+  /**
+   * An optional word pattern (regular expression) that describes valid contents for
+   * the given ranges. If no pattern is provided, the client configuration's word
+   * pattern will be used.
+   */
+  @Pure
+  public String getWordPattern() {
+    return this.wordPattern;
+  }
+  
+  /**
+   * An optional word pattern (regular expression) that describes valid contents for
+   * the given ranges. If no pattern is provided, the client configuration's word
+   * pattern will be used.
+   */
+  public void setWordPattern(final String wordPattern) {
+    this.wordPattern = wordPattern;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("ranges", this.ranges);
+    b.add("wordPattern", this.wordPattern);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    LinkedEditingRanges other = (LinkedEditingRanges) obj;
+    if (this.ranges == null) {
+      if (other.ranges != null)
+        return false;
+    } else if (!this.ranges.equals(other.ranges))
+      return false;
+    if (this.wordPattern == null) {
+      if (other.wordPattern != null)
+        return false;
+    } else if (!this.wordPattern.equals(other.wordPattern))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.ranges== null) ? 0 : this.ranges.hashCode());
+    return prime * result + ((this.wordPattern== null) ? 0 : this.wordPattern.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/Location.java b/java/org/eclipse/lsp4j/Location.java
new file mode 100644
index 0000000..7564be3
--- /dev/null
+++ b/java/org/eclipse/lsp4j/Location.java
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Represents a location inside a resource, such as a line inside a text file.
+ */
+@SuppressWarnings("all")
+public class Location {
+  @NonNull
+  private String uri;
+  
+  @NonNull
+  private Range range;
+  
+  public Location() {
+  }
+  
+  public Location(@NonNull final String uri, @NonNull final Range range) {
+    this.uri = Preconditions.<String>checkNotNull(uri, "uri");
+    this.range = Preconditions.<Range>checkNotNull(range, "range");
+  }
+  
+  @Pure
+  @NonNull
+  public String getUri() {
+    return this.uri;
+  }
+  
+  public void setUri(@NonNull final String uri) {
+    this.uri = Preconditions.checkNotNull(uri, "uri");
+  }
+  
+  @Pure
+  @NonNull
+  public Range getRange() {
+    return this.range;
+  }
+  
+  public void setRange(@NonNull final Range range) {
+    this.range = Preconditions.checkNotNull(range, "range");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("uri", this.uri);
+    b.add("range", this.range);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    Location other = (Location) obj;
+    if (this.uri == null) {
+      if (other.uri != null)
+        return false;
+    } else if (!this.uri.equals(other.uri))
+      return false;
+    if (this.range == null) {
+      if (other.range != null)
+        return false;
+    } else if (!this.range.equals(other.range))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.uri== null) ? 0 : this.uri.hashCode());
+    return prime * result + ((this.range== null) ? 0 : this.range.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/LocationLink.java b/java/org/eclipse/lsp4j/LocationLink.java
new file mode 100644
index 0000000..05910fb
--- /dev/null
+++ b/java/org/eclipse/lsp4j/LocationLink.java
@@ -0,0 +1,197 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Represents a link between a source and a target location.
+ */
+@SuppressWarnings("all")
+public class LocationLink {
+  /**
+   * Span of the origin of this link.
+   * <p>
+   * Used as the underlined span for mouse interaction. Defaults to the word range at
+   * the mouse position.
+   */
+  private Range originSelectionRange;
+  
+  /**
+   * The target resource identifier of this link.
+   */
+  @NonNull
+  private String targetUri;
+  
+  /**
+   * The full target range of this link. If the target for example is a symbol then target range is the
+   * range enclosing this symbol not including leading/trailing whitespace but everything else
+   * like comments. This information is typically used to highlight the range in the editor.
+   */
+  @NonNull
+  private Range targetRange;
+  
+  /**
+   * The range that should be selected and revealed when this link is being followed, e.g the name of a function.
+   * Must be contained by the the {@link #targetRange}. See also {@link DocumentSymbol#range}
+   */
+  @NonNull
+  private Range targetSelectionRange;
+  
+  public LocationLink() {
+  }
+  
+  public LocationLink(@NonNull final String targetUri, @NonNull final Range targetRange, @NonNull final Range targetSelectionRange) {
+    this.targetUri = Preconditions.<String>checkNotNull(targetUri, "targetUri");
+    this.targetRange = Preconditions.<Range>checkNotNull(targetRange, "targetRange");
+    this.targetSelectionRange = Preconditions.<Range>checkNotNull(targetSelectionRange, "targetSelectionRange");
+  }
+  
+  public LocationLink(@NonNull final String targetUri, @NonNull final Range targetRange, @NonNull final Range targetSelectionRange, final Range originSelectionRange) {
+    this(targetUri, targetRange, targetSelectionRange);
+    this.originSelectionRange = originSelectionRange;
+  }
+  
+  /**
+   * Span of the origin of this link.
+   * <p>
+   * Used as the underlined span for mouse interaction. Defaults to the word range at
+   * the mouse position.
+   */
+  @Pure
+  public Range getOriginSelectionRange() {
+    return this.originSelectionRange;
+  }
+  
+  /**
+   * Span of the origin of this link.
+   * <p>
+   * Used as the underlined span for mouse interaction. Defaults to the word range at
+   * the mouse position.
+   */
+  public void setOriginSelectionRange(final Range originSelectionRange) {
+    this.originSelectionRange = originSelectionRange;
+  }
+  
+  /**
+   * The target resource identifier of this link.
+   */
+  @Pure
+  @NonNull
+  public String getTargetUri() {
+    return this.targetUri;
+  }
+  
+  /**
+   * The target resource identifier of this link.
+   */
+  public void setTargetUri(@NonNull final String targetUri) {
+    this.targetUri = Preconditions.checkNotNull(targetUri, "targetUri");
+  }
+  
+  /**
+   * The full target range of this link. If the target for example is a symbol then target range is the
+   * range enclosing this symbol not including leading/trailing whitespace but everything else
+   * like comments. This information is typically used to highlight the range in the editor.
+   */
+  @Pure
+  @NonNull
+  public Range getTargetRange() {
+    return this.targetRange;
+  }
+  
+  /**
+   * The full target range of this link. If the target for example is a symbol then target range is the
+   * range enclosing this symbol not including leading/trailing whitespace but everything else
+   * like comments. This information is typically used to highlight the range in the editor.
+   */
+  public void setTargetRange(@NonNull final Range targetRange) {
+    this.targetRange = Preconditions.checkNotNull(targetRange, "targetRange");
+  }
+  
+  /**
+   * The range that should be selected and revealed when this link is being followed, e.g the name of a function.
+   * Must be contained by the the {@link #targetRange}. See also {@link DocumentSymbol#range}
+   */
+  @Pure
+  @NonNull
+  public Range getTargetSelectionRange() {
+    return this.targetSelectionRange;
+  }
+  
+  /**
+   * The range that should be selected and revealed when this link is being followed, e.g the name of a function.
+   * Must be contained by the the {@link #targetRange}. See also {@link DocumentSymbol#range}
+   */
+  public void setTargetSelectionRange(@NonNull final Range targetSelectionRange) {
+    this.targetSelectionRange = Preconditions.checkNotNull(targetSelectionRange, "targetSelectionRange");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("originSelectionRange", this.originSelectionRange);
+    b.add("targetUri", this.targetUri);
+    b.add("targetRange", this.targetRange);
+    b.add("targetSelectionRange", this.targetSelectionRange);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    LocationLink other = (LocationLink) obj;
+    if (this.originSelectionRange == null) {
+      if (other.originSelectionRange != null)
+        return false;
+    } else if (!this.originSelectionRange.equals(other.originSelectionRange))
+      return false;
+    if (this.targetUri == null) {
+      if (other.targetUri != null)
+        return false;
+    } else if (!this.targetUri.equals(other.targetUri))
+      return false;
+    if (this.targetRange == null) {
+      if (other.targetRange != null)
+        return false;
+    } else if (!this.targetRange.equals(other.targetRange))
+      return false;
+    if (this.targetSelectionRange == null) {
+      if (other.targetSelectionRange != null)
+        return false;
+    } else if (!this.targetSelectionRange.equals(other.targetSelectionRange))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.originSelectionRange== null) ? 0 : this.originSelectionRange.hashCode());
+    result = prime * result + ((this.targetUri== null) ? 0 : this.targetUri.hashCode());
+    result = prime * result + ((this.targetRange== null) ? 0 : this.targetRange.hashCode());
+    return prime * result + ((this.targetSelectionRange== null) ? 0 : this.targetSelectionRange.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/LogTraceParams.java b/java/org/eclipse/lsp4j/LogTraceParams.java
new file mode 100644
index 0000000..2d53791
--- /dev/null
+++ b/java/org/eclipse/lsp4j/LogTraceParams.java
@@ -0,0 +1,125 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A notification to log the trace of the server's execution. The amount and content of these notifications
+ * depends on the current trace configuration. If trace is 'off', the server should not send any logTrace
+ * notification. If trace is 'message', the server should not add the 'verbose' field.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class LogTraceParams {
+  /**
+   * The message to be logged.
+   */
+  @NonNull
+  private String message;
+  
+  /**
+   * Additional information that can be computed if the {@code trace} configuration
+   * is set to {@link TraceValue#Verbose}
+   */
+  private String verbose;
+  
+  public LogTraceParams() {
+  }
+  
+  public LogTraceParams(@NonNull final String message) {
+    this.message = Preconditions.<String>checkNotNull(message, "message");
+  }
+  
+  public LogTraceParams(@NonNull final String message, final String verbose) {
+    this.message = Preconditions.<String>checkNotNull(message, "message");
+    this.verbose = verbose;
+  }
+  
+  /**
+   * The message to be logged.
+   */
+  @Pure
+  @NonNull
+  public String getMessage() {
+    return this.message;
+  }
+  
+  /**
+   * The message to be logged.
+   */
+  public void setMessage(@NonNull final String message) {
+    this.message = Preconditions.checkNotNull(message, "message");
+  }
+  
+  /**
+   * Additional information that can be computed if the {@code trace} configuration
+   * is set to {@link TraceValue#Verbose}
+   */
+  @Pure
+  public String getVerbose() {
+    return this.verbose;
+  }
+  
+  /**
+   * Additional information that can be computed if the {@code trace} configuration
+   * is set to {@link TraceValue#Verbose}
+   */
+  public void setVerbose(final String verbose) {
+    this.verbose = verbose;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("message", this.message);
+    b.add("verbose", this.verbose);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    LogTraceParams other = (LogTraceParams) obj;
+    if (this.message == null) {
+      if (other.message != null)
+        return false;
+    } else if (!this.message.equals(other.message))
+      return false;
+    if (this.verbose == null) {
+      if (other.verbose != null)
+        return false;
+    } else if (!this.verbose.equals(other.verbose))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.message== null) ? 0 : this.message.hashCode());
+    return prime * result + ((this.verbose== null) ? 0 : this.verbose.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/MarkdownCapabilities.java b/java/org/eclipse/lsp4j/MarkdownCapabilities.java
new file mode 100644
index 0000000..d5ea5c0
--- /dev/null
+++ b/java/org/eclipse/lsp4j/MarkdownCapabilities.java
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Client capabilities specific to the used markdown parser.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class MarkdownCapabilities {
+  /**
+   * The name of the parser.
+   */
+  @NonNull
+  private String parser;
+  
+  /**
+   * The version of the parser.
+   */
+  private String version;
+  
+  public MarkdownCapabilities() {
+  }
+  
+  public MarkdownCapabilities(@NonNull final String parser) {
+    this.parser = Preconditions.<String>checkNotNull(parser, "parser");
+  }
+  
+  public MarkdownCapabilities(@NonNull final String parser, final String version) {
+    this(parser);
+    this.version = version;
+  }
+  
+  /**
+   * The name of the parser.
+   */
+  @Pure
+  @NonNull
+  public String getParser() {
+    return this.parser;
+  }
+  
+  /**
+   * The name of the parser.
+   */
+  public void setParser(@NonNull final String parser) {
+    this.parser = Preconditions.checkNotNull(parser, "parser");
+  }
+  
+  /**
+   * The version of the parser.
+   */
+  @Pure
+  public String getVersion() {
+    return this.version;
+  }
+  
+  /**
+   * The version of the parser.
+   */
+  public void setVersion(final String version) {
+    this.version = version;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("parser", this.parser);
+    b.add("version", this.version);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    MarkdownCapabilities other = (MarkdownCapabilities) obj;
+    if (this.parser == null) {
+      if (other.parser != null)
+        return false;
+    } else if (!this.parser.equals(other.parser))
+      return false;
+    if (this.version == null) {
+      if (other.version != null)
+        return false;
+    } else if (!this.version.equals(other.version))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.parser== null) ? 0 : this.parser.hashCode());
+    return prime * result + ((this.version== null) ? 0 : this.version.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/MarkedString.java b/java/org/eclipse/lsp4j/MarkedString.java
new file mode 100644
index 0000000..9945434
--- /dev/null
+++ b/java/org/eclipse/lsp4j/MarkedString.java
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * MarkedString can be used to render human readable text. It is either a markdown string
+ * or a code-block that provides a language and a code snippet. The language identifier
+ * is semantically equal to the optional language identifier in fenced code blocks in GitHub
+ * issues. See https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting
+ * <p>
+ * The pair of a language and a value is an equivalent to markdown:
+ * <pre>
+ * ```${language}
+ * ${value}
+ * ```
+ * </pre>
+ * <p>
+ * Note that markdown strings will be sanitized - that means html will be escaped.
+ * 
+ * @deprecated Use {@link MarkupContent} instead.
+ */
+@Deprecated
+@SuppressWarnings("all")
+public class MarkedString {
+  @NonNull
+  private String language;
+  
+  @NonNull
+  private String value;
+  
+  public MarkedString() {
+  }
+  
+  public MarkedString(@NonNull final String language, @NonNull final String value) {
+    this.language = Preconditions.<String>checkNotNull(language, "language");
+    this.value = Preconditions.<String>checkNotNull(value, "value");
+  }
+  
+  @Pure
+  @NonNull
+  public String getLanguage() {
+    return this.language;
+  }
+  
+  public void setLanguage(@NonNull final String language) {
+    this.language = Preconditions.checkNotNull(language, "language");
+  }
+  
+  @Pure
+  @NonNull
+  public String getValue() {
+    return this.value;
+  }
+  
+  public void setValue(@NonNull final String value) {
+    this.value = Preconditions.checkNotNull(value, "value");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("language", this.language);
+    b.add("value", this.value);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    MarkedString other = (MarkedString) obj;
+    if (this.language == null) {
+      if (other.language != null)
+        return false;
+    } else if (!this.language.equals(other.language))
+      return false;
+    if (this.value == null) {
+      if (other.value != null)
+        return false;
+    } else if (!this.value.equals(other.value))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.language== null) ? 0 : this.language.hashCode());
+    return prime * result + ((this.value== null) ? 0 : this.value.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/MarkupContent.java b/java/org/eclipse/lsp4j/MarkupContent.java
new file mode 100644
index 0000000..521fd67
--- /dev/null
+++ b/java/org/eclipse/lsp4j/MarkupContent.java
@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A MarkupContent literal represents a string value which content is interpreted based on its
+ * kind flag. Currently the protocol supports {@link MarkupKind#PLAINTEXT plaintext} and
+ * {@link MarkupKind#MARKDOWN markdown} as markup kinds.
+ * <p>
+ * If the kind is {@link MarkupKind#MARKDOWN markdown} then the value can contain fenced code blocks like in GitHub issues.
+ * See https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting
+ * <p>
+ * Please Note that clients might sanitize the return markdown. A client could decide to
+ * remove HTML from the markdown to avoid script execution.
+ */
+@SuppressWarnings("all")
+public class MarkupContent {
+  /**
+   * The type of the Markup.
+   */
+  @NonNull
+  private String kind;
+  
+  /**
+   * The content itself.
+   */
+  @NonNull
+  private String value;
+  
+  public MarkupContent() {
+  }
+  
+  public MarkupContent(@NonNull final String kind, @NonNull final String value) {
+    this.kind = Preconditions.<String>checkNotNull(kind, "kind");
+    this.value = Preconditions.<String>checkNotNull(value, "value");
+  }
+  
+  /**
+   * The type of the Markup.
+   */
+  @Pure
+  @NonNull
+  public String getKind() {
+    return this.kind;
+  }
+  
+  /**
+   * The type of the Markup.
+   */
+  public void setKind(@NonNull final String kind) {
+    this.kind = Preconditions.checkNotNull(kind, "kind");
+  }
+  
+  /**
+   * The content itself.
+   */
+  @Pure
+  @NonNull
+  public String getValue() {
+    return this.value;
+  }
+  
+  /**
+   * The content itself.
+   */
+  public void setValue(@NonNull final String value) {
+    this.value = Preconditions.checkNotNull(value, "value");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("kind", this.kind);
+    b.add("value", this.value);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    MarkupContent other = (MarkupContent) obj;
+    if (this.kind == null) {
+      if (other.kind != null)
+        return false;
+    } else if (!this.kind.equals(other.kind))
+      return false;
+    if (this.value == null) {
+      if (other.value != null)
+        return false;
+    } else if (!this.value.equals(other.value))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.kind== null) ? 0 : this.kind.hashCode());
+    return prime * result + ((this.value== null) ? 0 : this.value.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/MarkupKind.java b/java/org/eclipse/lsp4j/MarkupKind.java
new file mode 100644
index 0000000..3f2d353
--- /dev/null
+++ b/java/org/eclipse/lsp4j/MarkupKind.java
@@ -0,0 +1,33 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j;
+
+/**
+ * Describes the content type that a client supports in various
+ * result literals like `Hover`, `ParameterInfo` or `CompletionItem`.
+ *
+ * Please note that `MarkupKind`s must not start with a `$`. These kinds
+ * are reserved for internal usage.
+ */
+public final class MarkupKind {
+	private MarkupKind() {}
+
+	/**
+	 * Plain text is supported as a content format.
+	 */
+	public static final String PLAINTEXT = "plaintext";
+	
+	/**
+	 * Markdown is supported as a content format.
+	 */
+	public static final String MARKDOWN = "markdown";
+}
diff --git a/java/org/eclipse/lsp4j/MessageActionItem.java b/java/org/eclipse/lsp4j/MessageActionItem.java
new file mode 100644
index 0000000..c9cc7ff
--- /dev/null
+++ b/java/org/eclipse/lsp4j/MessageActionItem.java
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The show message request is sent from a server to a client to ask the client to display a particular message in the
+ * user class. In addition to the show message notification the request allows to pass actions and to wait for an
+ * answer from the client.
+ */
+@SuppressWarnings("all")
+public class MessageActionItem {
+  /**
+   * A short title like 'Retry', 'Open Log' etc.
+   */
+  @NonNull
+  private String title;
+  
+  public MessageActionItem() {
+  }
+  
+  public MessageActionItem(@NonNull final String title) {
+    this.title = Preconditions.<String>checkNotNull(title, "title");
+  }
+  
+  /**
+   * A short title like 'Retry', 'Open Log' etc.
+   */
+  @Pure
+  @NonNull
+  public String getTitle() {
+    return this.title;
+  }
+  
+  /**
+   * A short title like 'Retry', 'Open Log' etc.
+   */
+  public void setTitle(@NonNull final String title) {
+    this.title = Preconditions.checkNotNull(title, "title");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("title", this.title);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    MessageActionItem other = (MessageActionItem) obj;
+    if (this.title == null) {
+      if (other.title != null)
+        return false;
+    } else if (!this.title.equals(other.title))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.title== null) ? 0 : this.title.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/MessageParams.java b/java/org/eclipse/lsp4j/MessageParams.java
new file mode 100644
index 0000000..f648b4a
--- /dev/null
+++ b/java/org/eclipse/lsp4j/MessageParams.java
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.MessageType;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The show message notification is sent from a server to a client to ask the client to display a particular message
+ * in the user class.
+ * <p>
+ * The log message notification is send from the server to the client to ask the client to log a particular message.
+ */
+@SuppressWarnings("all")
+public class MessageParams {
+  /**
+   * The message type.
+   */
+  @NonNull
+  private MessageType type;
+  
+  /**
+   * The actual message.
+   */
+  @NonNull
+  private String message;
+  
+  public MessageParams() {
+  }
+  
+  public MessageParams(@NonNull final MessageType type, @NonNull final String message) {
+    this.type = Preconditions.<MessageType>checkNotNull(type, "type");
+    this.message = Preconditions.<String>checkNotNull(message, "message");
+  }
+  
+  /**
+   * The message type.
+   */
+  @Pure
+  @NonNull
+  public MessageType getType() {
+    return this.type;
+  }
+  
+  /**
+   * The message type.
+   */
+  public void setType(@NonNull final MessageType type) {
+    this.type = Preconditions.checkNotNull(type, "type");
+  }
+  
+  /**
+   * The actual message.
+   */
+  @Pure
+  @NonNull
+  public String getMessage() {
+    return this.message;
+  }
+  
+  /**
+   * The actual message.
+   */
+  public void setMessage(@NonNull final String message) {
+    this.message = Preconditions.checkNotNull(message, "message");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("type", this.type);
+    b.add("message", this.message);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    MessageParams other = (MessageParams) obj;
+    if (this.type == null) {
+      if (other.type != null)
+        return false;
+    } else if (!this.type.equals(other.type))
+      return false;
+    if (this.message == null) {
+      if (other.message != null)
+        return false;
+    } else if (!this.message.equals(other.message))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.type== null) ? 0 : this.type.hashCode());
+    return prime * result + ((this.message== null) ? 0 : this.message.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/MessageType.java b/java/org/eclipse/lsp4j/MessageType.java
new file mode 100644
index 0000000..1db3ac1
--- /dev/null
+++ b/java/org/eclipse/lsp4j/MessageType.java
@@ -0,0 +1,53 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j;
+
+public enum MessageType {
+	
+	/**
+	 * An error message.
+	 */
+	Error(1),
+	
+	/**
+	 * A warning message.
+	 */
+	Warning(2),
+	
+	/**
+	 * An information message.
+	 */
+	Info(3),
+	
+	/**
+	 * A log message.
+	 */
+	Log(4);
+	
+	private final int value;
+	
+	MessageType(int value) {
+		this.value = value;
+	}
+	
+	public int getValue() {
+		return value;
+	}
+	
+	public static MessageType forValue(int value) {
+		MessageType[] allValues = MessageType.values();
+		if (value < 1 || value > allValues.length)
+			throw new IllegalArgumentException("Illegal enum value: " + value);
+		return allValues[value - 1];
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/Moniker.java b/java/org/eclipse/lsp4j/Moniker.java
new file mode 100644
index 0000000..3ff0e9a
--- /dev/null
+++ b/java/org/eclipse/lsp4j/Moniker.java
@@ -0,0 +1,183 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Moniker definition to match LSIF 0.5 moniker definition.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class Moniker {
+  /**
+   * The scheme of the moniker. For example tsc or .Net
+   */
+  @NonNull
+  private String scheme;
+  
+  /**
+   * The identifier of the moniker. The value is opaque in LSIF however
+   * schema owners are allowed to define the structure if they want.
+   */
+  @NonNull
+  private String identifier;
+  
+  /**
+   * The scope in which the moniker is unique. Values are taken from {@link UniquenessLevel}.
+   */
+  @NonNull
+  private String unique;
+  
+  /**
+   * The moniker kind if known. Values are taken from {@link MonikerKind}.
+   */
+  private String kind;
+  
+  public Moniker() {
+  }
+  
+  public Moniker(@NonNull final String scheme, @NonNull final String identifier, @NonNull final String unique) {
+    this.scheme = Preconditions.<String>checkNotNull(scheme, "scheme");
+    this.identifier = Preconditions.<String>checkNotNull(identifier, "identifier");
+    this.unique = Preconditions.<String>checkNotNull(unique, "unique");
+  }
+  
+  public Moniker(@NonNull final String scheme, @NonNull final String identifier, @NonNull final String unique, final String kind) {
+    this(scheme, identifier, unique);
+    this.kind = kind;
+  }
+  
+  /**
+   * The scheme of the moniker. For example tsc or .Net
+   */
+  @Pure
+  @NonNull
+  public String getScheme() {
+    return this.scheme;
+  }
+  
+  /**
+   * The scheme of the moniker. For example tsc or .Net
+   */
+  public void setScheme(@NonNull final String scheme) {
+    this.scheme = Preconditions.checkNotNull(scheme, "scheme");
+  }
+  
+  /**
+   * The identifier of the moniker. The value is opaque in LSIF however
+   * schema owners are allowed to define the structure if they want.
+   */
+  @Pure
+  @NonNull
+  public String getIdentifier() {
+    return this.identifier;
+  }
+  
+  /**
+   * The identifier of the moniker. The value is opaque in LSIF however
+   * schema owners are allowed to define the structure if they want.
+   */
+  public void setIdentifier(@NonNull final String identifier) {
+    this.identifier = Preconditions.checkNotNull(identifier, "identifier");
+  }
+  
+  /**
+   * The scope in which the moniker is unique. Values are taken from {@link UniquenessLevel}.
+   */
+  @Pure
+  @NonNull
+  public String getUnique() {
+    return this.unique;
+  }
+  
+  /**
+   * The scope in which the moniker is unique. Values are taken from {@link UniquenessLevel}.
+   */
+  public void setUnique(@NonNull final String unique) {
+    this.unique = Preconditions.checkNotNull(unique, "unique");
+  }
+  
+  /**
+   * The moniker kind if known. Values are taken from {@link MonikerKind}.
+   */
+  @Pure
+  public String getKind() {
+    return this.kind;
+  }
+  
+  /**
+   * The moniker kind if known. Values are taken from {@link MonikerKind}.
+   */
+  public void setKind(final String kind) {
+    this.kind = kind;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("scheme", this.scheme);
+    b.add("identifier", this.identifier);
+    b.add("unique", this.unique);
+    b.add("kind", this.kind);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    Moniker other = (Moniker) obj;
+    if (this.scheme == null) {
+      if (other.scheme != null)
+        return false;
+    } else if (!this.scheme.equals(other.scheme))
+      return false;
+    if (this.identifier == null) {
+      if (other.identifier != null)
+        return false;
+    } else if (!this.identifier.equals(other.identifier))
+      return false;
+    if (this.unique == null) {
+      if (other.unique != null)
+        return false;
+    } else if (!this.unique.equals(other.unique))
+      return false;
+    if (this.kind == null) {
+      if (other.kind != null)
+        return false;
+    } else if (!this.kind.equals(other.kind))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.scheme== null) ? 0 : this.scheme.hashCode());
+    result = prime * result + ((this.identifier== null) ? 0 : this.identifier.hashCode());
+    result = prime * result + ((this.unique== null) ? 0 : this.unique.hashCode());
+    return prime * result + ((this.kind== null) ? 0 : this.kind.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/MonikerCapabilities.java b/java/org/eclipse/lsp4j/MonikerCapabilities.java
new file mode 100644
index 0000000..2e40ec1
--- /dev/null
+++ b/java/org/eclipse/lsp4j/MonikerCapabilities.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the {@code textDocument/moniker} request.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class MonikerCapabilities extends DynamicRegistrationCapabilities {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/MonikerKind.java b/java/org/eclipse/lsp4j/MonikerKind.java
new file mode 100644
index 0000000..d83db5e
--- /dev/null
+++ b/java/org/eclipse/lsp4j/MonikerKind.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright (c) 2020 TypeFox and others.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+package org.eclipse.lsp4j;
+
+/**
+ * The moniker kind.
+ * 
+ * Since 3.16.0
+ */
+public final class MonikerKind {
+	private MonikerKind() {
+	}
+
+	/**
+	 * The moniker represents a symbol that is imported into a project
+	 */
+	public static final String Import = "import";
+
+	/**
+	 * The moniker represents a symbol that is exported from a project
+	 */
+	public static final String Export = "export";
+
+	/**
+	 * The moniker represents a symbol that is local to a project (e.g. a local
+	 * variable of a function, a class not visible outside the project, ...)
+	 */
+	public static final String Local = "local";
+}
diff --git a/java/org/eclipse/lsp4j/MonikerOptions.java b/java/org/eclipse/lsp4j/MonikerOptions.java
new file mode 100644
index 0000000..02c3ea7
--- /dev/null
+++ b/java/org/eclipse/lsp4j/MonikerOptions.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Moniker options.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class MonikerOptions extends AbstractWorkDoneProgressOptions {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/MonikerParams.java b/java/org/eclipse/lsp4j/MonikerParams.java
new file mode 100644
index 0000000..3e0194d
--- /dev/null
+++ b/java/org/eclipse/lsp4j/MonikerParams.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.TextDocumentPositionAndWorkDoneProgressAndPartialResultParams;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The moniker request is sent from the client to the server to get the symbol monikers for a given text document position.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class MonikerParams extends TextDocumentPositionAndWorkDoneProgressAndPartialResultParams {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("partialResultToken", getPartialResultToken());
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("textDocument", getTextDocument());
+    b.add("uri", getUri());
+    b.add("position", getPosition());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/MonikerRegistrationOptions.java b/java/org/eclipse/lsp4j/MonikerRegistrationOptions.java
new file mode 100644
index 0000000..945d426
--- /dev/null
+++ b/java/org/eclipse/lsp4j/MonikerRegistrationOptions.java
@@ -0,0 +1,53 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractTextDocumentRegistrationAndWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Moniker registration options.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class MonikerRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/OnTypeFormattingCapabilities.java b/java/org/eclipse/lsp4j/OnTypeFormattingCapabilities.java
new file mode 100644
index 0000000..0f9bb77
--- /dev/null
+++ b/java/org/eclipse/lsp4j/OnTypeFormattingCapabilities.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the `textDocument/onTypeFormatting`
+ */
+@SuppressWarnings("all")
+public class OnTypeFormattingCapabilities extends DynamicRegistrationCapabilities {
+  public OnTypeFormattingCapabilities() {
+  }
+  
+  public OnTypeFormattingCapabilities(final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ParameterInformation.java b/java/org/eclipse/lsp4j/ParameterInformation.java
new file mode 100644
index 0000000..bfbae29
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ParameterInformation.java
@@ -0,0 +1,181 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.MarkupContent;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.messages.Tuple;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Represents a parameter of a callable-signature. A parameter can have a label and a doc-comment.
+ */
+@SuppressWarnings("all")
+public class ParameterInformation {
+  /**
+   * The label of this parameter information.
+   * <p>
+   * Either a string or an inclusive start and exclusive end offsets within its containing
+   * signature label (see {@link SignatureInformation#label}). The offsets are based on a UTF-16
+   * string representation as {@link Position} and {@link Range} does.
+   * <p>
+   * <em>Note</em>: a label of type string should be a substring of its containing signature label.
+   * Its intended use case is to highlight the parameter label part in the {@link SignatureInformation#label}.
+   */
+  @NonNull
+  private Either<String, Tuple.Two<Integer, Integer>> label;
+  
+  /**
+   * The human-readable doc-comment of this signature. Will be shown in the UI but can be omitted.
+   */
+  private Either<String, MarkupContent> documentation;
+  
+  public ParameterInformation() {
+  }
+  
+  public ParameterInformation(@NonNull final String label) {
+    this.setLabel(Preconditions.<String>checkNotNull(label, "label"));
+  }
+  
+  public ParameterInformation(@NonNull final String label, final String documentation) {
+    this(label);
+    this.setDocumentation(documentation);
+  }
+  
+  public ParameterInformation(@NonNull final String label, final MarkupContent documentation) {
+    this(label);
+    this.setDocumentation(documentation);
+  }
+  
+  /**
+   * The label of this parameter information.
+   * <p>
+   * Either a string or an inclusive start and exclusive end offsets within its containing
+   * signature label (see {@link SignatureInformation#label}). The offsets are based on a UTF-16
+   * string representation as {@link Position} and {@link Range} does.
+   * <p>
+   * <em>Note</em>: a label of type string should be a substring of its containing signature label.
+   * Its intended use case is to highlight the parameter label part in the {@link SignatureInformation#label}.
+   */
+  @Pure
+  @NonNull
+  public Either<String, Tuple.Two<Integer, Integer>> getLabel() {
+    return this.label;
+  }
+  
+  /**
+   * The label of this parameter information.
+   * <p>
+   * Either a string or an inclusive start and exclusive end offsets within its containing
+   * signature label (see {@link SignatureInformation#label}). The offsets are based on a UTF-16
+   * string representation as {@link Position} and {@link Range} does.
+   * <p>
+   * <em>Note</em>: a label of type string should be a substring of its containing signature label.
+   * Its intended use case is to highlight the parameter label part in the {@link SignatureInformation#label}.
+   */
+  public void setLabel(@NonNull final Either<String, Tuple.Two<Integer, Integer>> label) {
+    this.label = Preconditions.checkNotNull(label, "label");
+  }
+  
+  public void setLabel(final String label) {
+    if (label == null) {
+      Preconditions.checkNotNull(label, "label");
+      this.label = null;
+      return;
+    }
+    this.label = Either.forLeft(label);
+  }
+  
+  public void setLabel(final Tuple.Two<Integer, Integer> label) {
+    if (label == null) {
+      Preconditions.checkNotNull(label, "label");
+      this.label = null;
+      return;
+    }
+    this.label = Either.forRight(label);
+  }
+  
+  /**
+   * The human-readable doc-comment of this signature. Will be shown in the UI but can be omitted.
+   */
+  @Pure
+  public Either<String, MarkupContent> getDocumentation() {
+    return this.documentation;
+  }
+  
+  /**
+   * The human-readable doc-comment of this signature. Will be shown in the UI but can be omitted.
+   */
+  public void setDocumentation(final Either<String, MarkupContent> documentation) {
+    this.documentation = documentation;
+  }
+  
+  public void setDocumentation(final String documentation) {
+    if (documentation == null) {
+      this.documentation = null;
+      return;
+    }
+    this.documentation = Either.forLeft(documentation);
+  }
+  
+  public void setDocumentation(final MarkupContent documentation) {
+    if (documentation == null) {
+      this.documentation = null;
+      return;
+    }
+    this.documentation = Either.forRight(documentation);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("label", this.label);
+    b.add("documentation", this.documentation);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ParameterInformation other = (ParameterInformation) obj;
+    if (this.label == null) {
+      if (other.label != null)
+        return false;
+    } else if (!this.label.equals(other.label))
+      return false;
+    if (this.documentation == null) {
+      if (other.documentation != null)
+        return false;
+    } else if (!this.documentation.equals(other.documentation))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.label== null) ? 0 : this.label.hashCode());
+    return prime * result + ((this.documentation== null) ? 0 : this.documentation.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ParameterInformationCapabilities.java b/java/org/eclipse/lsp4j/ParameterInformationCapabilities.java
new file mode 100644
index 0000000..402c4bc
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ParameterInformationCapabilities.java
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Client capabilities specific to parameter information.
+ */
+@SuppressWarnings("all")
+public class ParameterInformationCapabilities {
+  /**
+   * The client supports processing label offsets instead of a
+   * simple label string.
+   * <p>
+   * Since 3.14.0
+   */
+  private Boolean labelOffsetSupport;
+  
+  public ParameterInformationCapabilities() {
+  }
+  
+  public ParameterInformationCapabilities(final Boolean labelOffsetSupport) {
+    this.labelOffsetSupport = labelOffsetSupport;
+  }
+  
+  /**
+   * The client supports processing label offsets instead of a
+   * simple label string.
+   * <p>
+   * Since 3.14.0
+   */
+  @Pure
+  public Boolean getLabelOffsetSupport() {
+    return this.labelOffsetSupport;
+  }
+  
+  /**
+   * The client supports processing label offsets instead of a
+   * simple label string.
+   * <p>
+   * Since 3.14.0
+   */
+  public void setLabelOffsetSupport(final Boolean labelOffsetSupport) {
+    this.labelOffsetSupport = labelOffsetSupport;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("labelOffsetSupport", this.labelOffsetSupport);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ParameterInformationCapabilities other = (ParameterInformationCapabilities) obj;
+    if (this.labelOffsetSupport == null) {
+      if (other.labelOffsetSupport != null)
+        return false;
+    } else if (!this.labelOffsetSupport.equals(other.labelOffsetSupport))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.labelOffsetSupport== null) ? 0 : this.labelOffsetSupport.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/PartialResultParams.java b/java/org/eclipse/lsp4j/PartialResultParams.java
new file mode 100644
index 0000000..53b79c9
--- /dev/null
+++ b/java/org/eclipse/lsp4j/PartialResultParams.java
@@ -0,0 +1,34 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+
+/**
+ * A parameter literal used to pass a partial result token.
+ * <p>
+ * Since 3.15.0
+ */
+@SuppressWarnings("all")
+public interface PartialResultParams {
+  /**
+   * An optional token that a server can use to report partial results (e.g. streaming) to
+   * the client.
+   */
+  Either<String, Integer> getPartialResultToken();
+  
+  /**
+   * An optional token that a server can use to report partial results (e.g. streaming) to
+   * the client.
+   */
+  void setPartialResultToken(final Either<String, Integer> token);
+}
diff --git a/java/org/eclipse/lsp4j/Position.java b/java/org/eclipse/lsp4j/Position.java
new file mode 100644
index 0000000..c9f6a34
--- /dev/null
+++ b/java/org/eclipse/lsp4j/Position.java
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Position in a text document expressed as zero-based line and character offset.
+ */
+@SuppressWarnings("all")
+public class Position {
+  /**
+   * Line position in a document (zero-based).
+   */
+  private int line;
+  
+  /**
+   * Character offset on a line in a document (zero-based).
+   */
+  private int character;
+  
+  public Position() {
+  }
+  
+  public Position(final int line, final int character) {
+    this.line = line;
+    this.character = character;
+  }
+  
+  /**
+   * Line position in a document (zero-based).
+   */
+  @Pure
+  public int getLine() {
+    return this.line;
+  }
+  
+  /**
+   * Line position in a document (zero-based).
+   */
+  public void setLine(final int line) {
+    this.line = line;
+  }
+  
+  /**
+   * Character offset on a line in a document (zero-based).
+   */
+  @Pure
+  public int getCharacter() {
+    return this.character;
+  }
+  
+  /**
+   * Character offset on a line in a document (zero-based).
+   */
+  public void setCharacter(final int character) {
+    this.character = character;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("line", this.line);
+    b.add("character", this.character);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    Position other = (Position) obj;
+    if (other.line != this.line)
+      return false;
+    if (other.character != this.character)
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + this.line;
+    return prime * result + this.character;
+  }
+}
diff --git a/java/org/eclipse/lsp4j/PrepareRenameParams.java b/java/org/eclipse/lsp4j/PrepareRenameParams.java
new file mode 100644
index 0000000..3c72caa
--- /dev/null
+++ b/java/org/eclipse/lsp4j/PrepareRenameParams.java
@@ -0,0 +1,63 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.Position;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.TextDocumentPositionParams;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The prepare rename request is sent from the client to the server to setup and test the validity of a
+ * rename operation at a given location.
+ */
+@SuppressWarnings("all")
+public class PrepareRenameParams extends TextDocumentPositionParams {
+  public PrepareRenameParams() {
+  }
+  
+  public PrepareRenameParams(@NonNull final TextDocumentIdentifier textDocument, @NonNull final Position position) {
+    super(textDocument, position);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("textDocument", getTextDocument());
+    b.add("uri", getUri());
+    b.add("position", getPosition());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/PrepareRenameResult.java b/java/org/eclipse/lsp4j/PrepareRenameResult.java
new file mode 100644
index 0000000..1786e83
--- /dev/null
+++ b/java/org/eclipse/lsp4j/PrepareRenameResult.java
@@ -0,0 +1,118 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * One of the result types of the `textDocument/prepareRename` request.
+ * Provides the range of the string to rename and a placeholder text of the string content to be renamed.
+ */
+@SuppressWarnings("all")
+public class PrepareRenameResult {
+  /**
+   * The range of the string to rename
+   */
+  @NonNull
+  private Range range;
+  
+  /**
+   * A placeholder text of the string content to be renamed.
+   */
+  @NonNull
+  private String placeholder;
+  
+  public PrepareRenameResult() {
+  }
+  
+  public PrepareRenameResult(@NonNull final Range range, @NonNull final String placeholder) {
+    this.range = Preconditions.<Range>checkNotNull(range, "range");
+    this.placeholder = Preconditions.<String>checkNotNull(placeholder, "placeholder");
+  }
+  
+  /**
+   * The range of the string to rename
+   */
+  @Pure
+  @NonNull
+  public Range getRange() {
+    return this.range;
+  }
+  
+  /**
+   * The range of the string to rename
+   */
+  public void setRange(@NonNull final Range range) {
+    this.range = Preconditions.checkNotNull(range, "range");
+  }
+  
+  /**
+   * A placeholder text of the string content to be renamed.
+   */
+  @Pure
+  @NonNull
+  public String getPlaceholder() {
+    return this.placeholder;
+  }
+  
+  /**
+   * A placeholder text of the string content to be renamed.
+   */
+  public void setPlaceholder(@NonNull final String placeholder) {
+    this.placeholder = Preconditions.checkNotNull(placeholder, "placeholder");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("range", this.range);
+    b.add("placeholder", this.placeholder);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    PrepareRenameResult other = (PrepareRenameResult) obj;
+    if (this.range == null) {
+      if (other.range != null)
+        return false;
+    } else if (!this.range.equals(other.range))
+      return false;
+    if (this.placeholder == null) {
+      if (other.placeholder != null)
+        return false;
+    } else if (!this.placeholder.equals(other.placeholder))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.range== null) ? 0 : this.range.hashCode());
+    return prime * result + ((this.placeholder== null) ? 0 : this.placeholder.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/PrepareSupportDefaultBehavior.java b/java/org/eclipse/lsp4j/PrepareSupportDefaultBehavior.java
new file mode 100644
index 0000000..014f3d7
--- /dev/null
+++ b/java/org/eclipse/lsp4j/PrepareSupportDefaultBehavior.java
@@ -0,0 +1,45 @@
+/******************************************************************************
+ * Copyright (c) 2020 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j;
+
+/**
+ * The value indicates the default behavior used by the
+ * client.
+ *
+ * Since version 3.16.0
+ */
+public enum PrepareSupportDefaultBehavior {
+	
+	/**
+	 * The client's default behavior is to select the identifier
+	 * according the to language's syntax rule.
+	 */
+	Identifier(1);
+	
+	private final int value;
+	
+	PrepareSupportDefaultBehavior(int value) {
+		this.value = value;
+	}
+	
+	public int getValue() {
+		return value;
+	}
+	
+	public static PrepareSupportDefaultBehavior forValue(int value) {
+		PrepareSupportDefaultBehavior[] allValues = PrepareSupportDefaultBehavior.values();
+		if (value < 1 || value > allValues.length)
+			throw new IllegalArgumentException("Illegal enum value: " + value);
+		return allValues[value - 1];
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/ProgressParams.java b/java/org/eclipse/lsp4j/ProgressParams.java
new file mode 100644
index 0000000..8934492
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ProgressParams.java
@@ -0,0 +1,145 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import com.google.gson.annotations.JsonAdapter;
+import org.eclipse.lsp4j.WorkDoneProgressNotification;
+import org.eclipse.lsp4j.adapters.ProgressNotificationAdapter;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The base protocol offers also support to report progress in a generic fashion.
+ * This mechanism can be used to report any kind of progress including work done progress
+ * (usually used to report progress in the user interface using a progress bar)
+ * and partial result progress to support streaming of results.
+ * A progress notification has the following properties:
+ * <p>
+ * Since 3.15.0
+ */
+@SuppressWarnings("all")
+public class ProgressParams {
+  /**
+   * The progress token provided by the client or server.
+   */
+  @NonNull
+  private Either<String, Integer> token;
+  
+  /**
+   * The progress data.
+   */
+  @NonNull
+  @JsonAdapter(ProgressNotificationAdapter.class)
+  private Either<WorkDoneProgressNotification, Object> value;
+  
+  public ProgressParams() {
+  }
+  
+  public ProgressParams(@NonNull final Either<String, Integer> token, @NonNull final Either<WorkDoneProgressNotification, Object> value) {
+    this.token = Preconditions.<Either<String, Integer>>checkNotNull(token, "token");
+    this.value = Preconditions.<Either<WorkDoneProgressNotification, Object>>checkNotNull(value, "value");
+  }
+  
+  /**
+   * The progress token provided by the client or server.
+   */
+  @Pure
+  @NonNull
+  public Either<String, Integer> getToken() {
+    return this.token;
+  }
+  
+  /**
+   * The progress token provided by the client or server.
+   */
+  public void setToken(@NonNull final Either<String, Integer> token) {
+    this.token = Preconditions.checkNotNull(token, "token");
+  }
+  
+  public void setToken(final String token) {
+    if (token == null) {
+      Preconditions.checkNotNull(token, "token");
+      this.token = null;
+      return;
+    }
+    this.token = Either.forLeft(token);
+  }
+  
+  public void setToken(final Integer token) {
+    if (token == null) {
+      Preconditions.checkNotNull(token, "token");
+      this.token = null;
+      return;
+    }
+    this.token = Either.forRight(token);
+  }
+  
+  /**
+   * The progress data.
+   */
+  @Pure
+  @NonNull
+  public Either<WorkDoneProgressNotification, Object> getValue() {
+    return this.value;
+  }
+  
+  /**
+   * The progress data.
+   */
+  public void setValue(@NonNull final Either<WorkDoneProgressNotification, Object> value) {
+    this.value = Preconditions.checkNotNull(value, "value");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("token", this.token);
+    b.add("value", this.value);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ProgressParams other = (ProgressParams) obj;
+    if (this.token == null) {
+      if (other.token != null)
+        return false;
+    } else if (!this.token.equals(other.token))
+      return false;
+    if (this.value == null) {
+      if (other.value != null)
+        return false;
+    } else if (!this.value.equals(other.value))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.token== null) ? 0 : this.token.hashCode());
+    return prime * result + ((this.value== null) ? 0 : this.value.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/Protocol.xtend b/java/org/eclipse/lsp4j/Protocol.xtend
new file mode 100644
index 0000000..5da70ae
--- /dev/null
+++ b/java/org/eclipse/lsp4j/Protocol.xtend
@@ -0,0 +1,8148 @@
+/******************************************************************************
+ * Copyright (c) 2016-2018 TypeFox and others.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j
+
+import com.google.common.annotations.Beta
+import com.google.gson.annotations.JsonAdapter
+import java.util.ArrayList
+import java.util.Arrays
+import java.util.LinkedHashMap
+import java.util.List
+import java.util.Map
+import org.eclipse.lsp4j.adapters.CompletionItemTextEditTypeAdapter
+import org.eclipse.lsp4j.adapters.DocumentChangeListAdapter
+import org.eclipse.lsp4j.adapters.HoverTypeAdapter
+import org.eclipse.lsp4j.adapters.InitializeParamsTypeAdapter
+import org.eclipse.lsp4j.adapters.ProgressNotificationAdapter
+import org.eclipse.lsp4j.adapters.ResourceChangeListAdapter
+import org.eclipse.lsp4j.adapters.ResourceOperationTypeAdapter
+import org.eclipse.lsp4j.adapters.SymbolInformationTypeAdapter
+import org.eclipse.lsp4j.adapters.VersionedTextDocumentIdentifierTypeAdapter
+import org.eclipse.lsp4j.generator.JsonRpcData
+import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter
+import org.eclipse.lsp4j.jsonrpc.messages.Either
+import org.eclipse.lsp4j.jsonrpc.messages.Either3
+import org.eclipse.lsp4j.jsonrpc.messages.Tuple
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull
+import org.eclipse.lsp4j.util.Preconditions
+
+@JsonRpcData
+class DynamicRegistrationCapabilities {
+	/**
+	 * Supports dynamic registration.
+	 */
+	Boolean dynamicRegistration
+
+	new() {
+	}
+
+	new(Boolean dynamicRegistration) {
+		this.dynamicRegistration = dynamicRegistration
+	}
+}
+
+/**
+ * Capabilities specific to {@link WorkspaceEdit}s
+ */
+@JsonRpcData
+class WorkspaceEditCapabilities {
+	/**
+	 * The client supports versioned document changes in {@link WorkspaceEdit}s
+	 */
+	Boolean documentChanges
+
+	/**
+	 * The client supports resource changes
+	 * in {@link WorkspaceEdit}s.
+	 *
+	 * @deprecated Since LSP introduced resource operations, use {@link #resourceOperations}
+	 */
+	@Deprecated
+	@Beta
+	Boolean resourceChanges
+
+	/**
+	 * The resource operations the client supports. Clients should at least
+	 * support 'create', 'rename' and 'delete' files and folders.
+	 * <p>
+	 * See {@link ResourceOperationKind} for allowed values.
+	 * <p>
+	 * Since 3.13.0
+	 */
+	List<String> resourceOperations
+
+	/**
+	 * The failure handling strategy of a client if applying the workspace edit
+	 * fails.
+	 * <p>
+	 * See {@link FailureHandlingKind} for allowed values.
+	 * <p>
+	 * Since 3.13.0
+	 */
+	String failureHandling
+
+	/**
+	 * Whether the client normalizes line endings to the client specific
+	 * setting.
+	 * <p>
+	 * If set to {@code true} the client will normalize line ending characters
+	 * in a workspace edit to the client specific new line character(s).
+	 * <p>
+	 * Since 3.16.0
+	 */
+	Boolean normalizesLineEndings
+
+	/**
+	 * Whether the client in general supports change annotations on text edits,
+	 * create file, rename file and delete file changes.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	WorkspaceEditChangeAnnotationSupportCapabilities changeAnnotationSupport
+
+	new() {
+	}
+
+	@Deprecated
+	new(Boolean documentChanges) {
+		this.documentChanges = documentChanges
+	}
+}
+
+/**
+ * Capabilities specific to the `workspace/didChangeConfiguration` notification.
+ */
+@JsonRpcData
+class DidChangeConfigurationCapabilities extends DynamicRegistrationCapabilities {
+	new() {
+	}
+
+	new(Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+	}
+}
+
+/**
+ * Capabilities specific to the `workspace/didChangeWatchedFiles` notification.
+ */
+@JsonRpcData
+class DidChangeWatchedFilesCapabilities extends DynamicRegistrationCapabilities {
+	new() {
+	}
+
+	new(Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+	}
+}
+
+/**
+ * Capabilities specific to the `workspace/symbol` request.
+ * Referred to in the spec as WorkspaceSymbolClientCapabilities.
+ */
+@JsonRpcData
+class SymbolCapabilities extends DynamicRegistrationCapabilities {
+
+	/**
+	 * Specific capabilities for the {@link SymbolKind} in the `workspace/symbol` request.
+	 */
+	SymbolKindCapabilities symbolKind
+
+	/**
+	 * The client supports tags on {@link SymbolInformation}.
+	 * Clients supporting tags have to handle unknown tags gracefully.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	SymbolTagSupportCapabilities tagSupport
+
+	new() {
+	}
+
+	new(Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+	}
+
+	new(SymbolKindCapabilities symbolKind) {
+		this.symbolKind = symbolKind
+	}
+
+	new(SymbolKindCapabilities symbolKind, Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+		this.symbolKind = symbolKind
+	}
+}
+
+/**
+ * Capabilities specific to the `workspace/executeCommand` request.
+ */
+@JsonRpcData
+class ExecuteCommandCapabilities extends DynamicRegistrationCapabilities {
+	new() {
+	}
+
+	new(Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+	}
+}
+
+/**
+ * Workspace specific client capabilities.
+ */
+@JsonRpcData
+class WorkspaceClientCapabilities {
+	/**
+	 * The client supports applying batch edits to the workspace by supporting
+	 * the request 'workspace/applyEdit'.
+	 */
+	Boolean applyEdit
+
+	/**
+	 * Capabilities specific to {@link WorkspaceEdit}s
+	 */
+	WorkspaceEditCapabilities workspaceEdit
+
+	/**
+	 * Capabilities specific to the `workspace/didChangeConfiguration` notification.
+	 */
+	DidChangeConfigurationCapabilities didChangeConfiguration
+
+	/**
+	 * Capabilities specific to the `workspace/didChangeWatchedFiles` notification.
+	 */
+	DidChangeWatchedFilesCapabilities didChangeWatchedFiles
+
+	/**
+	 * Capabilities specific to the `workspace/symbol` request.
+	 */
+	SymbolCapabilities symbol
+
+	/**
+	 * Capabilities specific to the `workspace/executeCommand` request.
+	 */
+	ExecuteCommandCapabilities executeCommand
+
+	/**
+	 * The client has support for workspace folders.
+	 * <p>
+	 * Since 3.6.0
+	 */
+	Boolean workspaceFolders
+
+	/**
+	 * The client supports `workspace/configuration` requests.
+	 * <p>
+	 * Since 3.6.0
+	 */
+	Boolean configuration
+
+	/**
+	 * Capabilities specific to the semantic token requests scoped to the
+	 * workspace.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	SemanticTokensWorkspaceCapabilities semanticTokens
+
+	/**
+	 * Capabilities specific to the code lens requests scoped to the
+	 * workspace.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	CodeLensWorkspaceCapabilities codeLens
+
+	/**
+	 * The client has support for file requests/notifications.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	FileOperationsWorkspaceCapabilities fileOperations
+}
+
+@JsonRpcData
+class SynchronizationCapabilities extends DynamicRegistrationCapabilities {
+	/**
+	 * The client supports sending will save notifications.
+	 */
+	Boolean willSave
+
+	/**
+	 * The client supports sending a will save request and
+	 * waits for a response providing text edits which will
+	 * be applied to the document before it is saved.
+	 */
+	Boolean willSaveWaitUntil
+
+	/**
+	 * The client supports did save notifications.
+	 */
+	Boolean didSave
+
+	new() {
+	}
+
+	new(Boolean willSave, Boolean willSaveWaitUntil, Boolean didSave) {
+		this.willSave = willSave
+		this.willSaveWaitUntil = willSaveWaitUntil
+		this.didSave = didSave
+	}
+
+	new(Boolean willSave, Boolean willSaveWaitUntil, Boolean didSave, Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+		this.willSave = willSave
+		this.willSaveWaitUntil = willSaveWaitUntil
+		this.didSave = didSave
+	}
+}
+
+/**
+ * The client supports the following {@link CompletionItem} specific capabilities.
+ */
+@JsonRpcData
+class CompletionItemCapabilities {
+	/**
+	 * Client supports snippets as insert text.
+	 * <p>
+	 * A snippet can define tab stops and placeholders with `$1`, `$2`
+	 * and `${3:foo}`. `$0` defines the final tab stop, it defaults to
+	 * the end of the snippet. Placeholders with equal identifiers are linked,
+	 * that is typing in one will update others too.
+	 */
+	Boolean snippetSupport
+
+	/**
+	 * Client supports commit characters on a completion item.
+	 */
+	Boolean commitCharactersSupport
+
+	/**
+	 * Client supports the following content formats for the documentation
+	 * property. The order describes the preferred format of the client.
+	 */
+	List<String> documentationFormat
+
+	/**
+	 * Client supports the deprecated property on a completion item.
+	 */
+	Boolean deprecatedSupport
+
+	/**
+	 * Client supports the preselect property on a completion item.
+	 */
+	Boolean preselectSupport
+
+	/**
+	 * Client supports the tag property on a completion item. Clients supporting
+	 * tags have to handle unknown tags gracefully. Clients especially need to
+	 * preserve unknown tags when sending a completion item back to the server in
+	 * a resolve call.
+	 * <p>
+	 * Since 3.15.0
+	 */
+	CompletionItemTagSupportCapabilities tagSupport
+
+	/**
+	 * Client support insert replace edit to control different behavior if a
+	 * completion item is inserted in the text or should replace text.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	Boolean insertReplaceSupport
+
+	/**
+	 * Indicates which properties a client can resolve lazily on a completion
+	 * item. Before version 3.16.0 only the predefined properties {@link CompletionItem#documentation}
+	 * and {@link CompletionItem#detail} could be resolved lazily.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	CompletionItemResolveSupportCapabilities resolveSupport
+
+	/**
+	 * The client supports the {@link CompletionItem#insertTextMode} property on
+	 * a completion item to override the whitespace handling mode
+	 * as defined by the client.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	CompletionItemInsertTextModeSupportCapabilities insertTextModeSupport
+
+	new() {
+	}
+
+	new(Boolean snippetSupport) {
+		this.snippetSupport = snippetSupport
+	}
+}
+
+/**
+ * Client supports the tag property on a completion item. Clients supporting
+ * tags have to handle unknown tags gracefully. Clients especially need to
+ * preserve unknown tags when sending a completion item back to the server in
+ * a resolve call.
+ * <p>
+ * Since 3.15.0
+ */
+@JsonRpcData
+class CompletionItemTagSupportCapabilities {
+	/**
+	* The tags supported by the client.
+	*/
+	@NonNull
+	List<CompletionItemTag> valueSet
+
+	new() {
+		this.valueSet = new ArrayList
+	}
+
+	new(@NonNull List<CompletionItemTag> valueSet) {
+		this.valueSet = Preconditions.checkNotNull(valueSet, 'valueSet')
+	}
+}
+
+/**
+ * Indicates which properties a client can resolve lazily on a completion
+ * item. Before version 3.16.0 only the predefined properties {@link CompletionItem#documentation}
+ * and {@link CompletionItem#detail} could be resolved lazily.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class CompletionItemResolveSupportCapabilities {
+	/**
+	 * The properties that a client can resolve lazily.
+	 */
+	@NonNull
+	List<String> properties
+
+	new() {
+		this.properties = new ArrayList
+	}
+
+	new(@NonNull List<String> properties) {
+		this.properties = Preconditions.checkNotNull(properties, 'properties')
+	}
+}
+
+/**
+ * The client supports the {@link CompletionItem#insertTextMode} property on
+ * a completion item to override the whitespace handling mode
+ * as defined by the client.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class CompletionItemInsertTextModeSupportCapabilities {
+	@NonNull
+	List<InsertTextMode> valueSet
+
+	new() {
+		this.valueSet = new ArrayList
+	}
+
+	new(@NonNull List<InsertTextMode> valueSet) {
+		this.valueSet = Preconditions.checkNotNull(valueSet, 'valueSet')
+	}
+}
+
+/**
+ * The client supports the following {@link CompletionItemKind} specific
+ * capabilities.
+ */
+@JsonRpcData
+class CompletionItemKindCapabilities {
+	/**
+	 * The completion item kind values the client supports. When this
+	 * property exists the client also guarantees that it will
+	 * handle values outside its set gracefully and falls back
+	 * to a default value when unknown.
+	 * <p>
+	 * If this property is not present the client only supports
+	 * the completion items kinds from {@link CompletionItemKind#Text} to
+	 * {@link CompletionItemKind#Reference} as defined in the initial version of the protocol.
+	 */
+	List<CompletionItemKind> valueSet
+
+	new() {
+	}
+
+	new(List<CompletionItemKind> valueSet) {
+		this.valueSet = valueSet
+	}
+}
+
+/**
+ * Capabilities specific to the `textDocument/completion`
+ */
+@JsonRpcData
+class CompletionCapabilities extends DynamicRegistrationCapabilities {
+	/**
+	 * The client supports the following {@link CompletionItem} specific
+	 * capabilities.
+	 */
+	CompletionItemCapabilities completionItem
+
+	/**
+	 * The client supports the following {@link CompletionItemKind} specific
+	 * capabilities.
+	 */
+	CompletionItemKindCapabilities completionItemKind
+
+	/**
+	 * The client supports sending additional context information for a
+	 * `textDocument/completion` request.
+	 */
+	Boolean contextSupport
+
+	new() {
+	}
+
+	new(CompletionItemCapabilities completionItem) {
+		this.completionItem = completionItem
+	}
+
+	new(CompletionItemKindCapabilities completionItemKind) {
+		this.completionItemKind = completionItemKind
+	}
+
+	new(Boolean contextSupport) {
+		this.contextSupport = contextSupport
+	}
+}
+
+/**
+ * Capabilities specific to the `textDocument/hover`
+ */
+@JsonRpcData
+class HoverCapabilities extends DynamicRegistrationCapabilities {
+	/**
+	 * Client supports the following content formats if the content
+	 * property refers to {@link MarkupContent}.
+	 * The order describes the preferred format of the client.
+	 * <p>
+	 * See {@link MarkupKind} for allowed values.
+	 */
+	List<String> contentFormat
+
+	new() {
+	}
+
+	new(Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+	}
+
+	new(List<String> contentFormat, Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+		this.contentFormat = contentFormat
+	}
+}
+
+/**
+ * The client supports the following {@link SignatureInformation} specific properties.
+ */
+@JsonRpcData
+class SignatureInformationCapabilities {
+	/**
+	 * Client supports the following content formats for the documentation
+	 * property. The order describes the preferred format of the client.
+	 * <p>
+	 * See {@link MarkupKind} for allowed values.
+	 */
+	List<String> documentationFormat
+
+	/**
+	 * Client capabilities specific to parameter information.
+	 */
+	ParameterInformationCapabilities parameterInformation
+
+	/**
+	 * The client supports the {@link SignatureInformation#activeParameter} property.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	Boolean activeParameterSupport
+
+	new() {
+	}
+
+	new(List<String> documentationFormat) {
+		this.documentationFormat = documentationFormat
+	}
+}
+
+/**
+ * Client capabilities specific to parameter information.
+ */
+@JsonRpcData
+class ParameterInformationCapabilities {
+	/**
+	 * The client supports processing label offsets instead of a
+	 * simple label string.
+	 * <p>
+	 * Since 3.14.0
+	 */
+	Boolean labelOffsetSupport
+
+	new() {
+	}
+
+	new(Boolean labelOffsetSupport) {
+		this.labelOffsetSupport = labelOffsetSupport
+	}
+}
+
+/**
+ * Capabilities specific to the `textDocument/signatureHelp`
+ */
+@JsonRpcData
+class SignatureHelpCapabilities extends DynamicRegistrationCapabilities {
+	/**
+	 * The client supports the following {@link SignatureInformation}
+	 * specific properties.
+	 */
+	SignatureInformationCapabilities signatureInformation
+
+	/**
+	 * The client supports to send additional context information for a
+	 * `textDocument/signatureHelp` request. A client that opts into
+	 * contextSupport will also support {@link SignatureHelpOptions#retriggerCharacters}.
+	 * <p>
+	 * Since 3.15.0
+	 */
+	Boolean contextSupport
+
+	new() {
+	}
+
+	new(Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+	}
+
+	new(SignatureInformationCapabilities signatureInformation, Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+		this.signatureInformation = signatureInformation
+	}
+}
+
+/**
+ * Capabilities specific to the `textDocument/references`
+ */
+@JsonRpcData
+class ReferencesCapabilities extends DynamicRegistrationCapabilities {
+	new() {
+	}
+
+	new(Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+	}
+}
+
+/**
+ * Capabilities specific to the `textDocument/documentHighlight`
+ */
+@JsonRpcData
+class DocumentHighlightCapabilities extends DynamicRegistrationCapabilities {
+	new() {
+	}
+
+	new(Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+	}
+}
+
+/**
+ * Specific capabilities for the {@link SymbolKind}.
+ */
+@JsonRpcData
+class SymbolKindCapabilities {
+	/**
+	 * The symbol kind values the client supports. When this
+	 * property exists the client also guarantees that it will
+	 * handle values outside its set gracefully and falls back
+	 * to a default value when unknown.
+	 * <p>
+	 * If this property is not present the client only supports
+	 * the symbol kinds from {@link SymbolKind#File} to
+	 * {@link SymbolKind#Array} as defined in the initial version of the protocol.
+	 */
+	List<SymbolKind> valueSet
+
+	new() {
+	}
+
+	new(List<SymbolKind> valueSet) {
+		this.valueSet = valueSet
+	}
+}
+
+/**
+ * Specific capabilities for the {@link SymbolTag}.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class SymbolTagSupportCapabilities {
+	/**
+	 * The tags supported by the client.
+	 */
+	@NonNull
+	List<SymbolTag> valueSet
+
+	new() {
+		this.valueSet = new ArrayList
+	}
+
+	new(@NonNull List<SymbolTag> valueSet) {
+		this.valueSet = Preconditions.checkNotNull(valueSet, 'valueSet')
+	}
+}
+
+/**
+ * Capabilities specific to the `textDocument/documentSymbol`
+ */
+@JsonRpcData
+class DocumentSymbolCapabilities extends DynamicRegistrationCapabilities {
+	/**
+	 * Specific capabilities for the {@link SymbolKind}.
+	 */
+	SymbolKindCapabilities symbolKind
+
+	/**
+	 * The client support hierarchical document symbols.
+	 */
+	Boolean hierarchicalDocumentSymbolSupport
+
+	/**
+	 * The client supports tags on {@link SymbolInformation}. Tags are supported on
+	 * {@link DocumentSymbol} if {@link #hierarchicalDocumentSymbolSupport} is set to true.
+	 * Clients supporting tags have to handle unknown tags gracefully.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	SymbolTagSupportCapabilities tagSupport
+
+	/**
+	 * The client supports an additional label presented in the UI when
+	 * registering a document symbol provider.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	Boolean labelSupport
+
+	new() {
+	}
+
+	new(Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+	}
+
+	new(SymbolKindCapabilities symbolKind) {
+		this.symbolKind = symbolKind
+	}
+
+	new(SymbolKindCapabilities symbolKind, Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+		this.symbolKind = symbolKind
+	}
+
+	new(SymbolKindCapabilities symbolKind, Boolean dynamicRegistration, Boolean hierarchicalDocumentSymbolSupport) {
+		super(dynamicRegistration)
+		this.symbolKind = symbolKind
+		this.hierarchicalDocumentSymbolSupport = hierarchicalDocumentSymbolSupport
+	}
+}
+
+/**
+ * Capabilities specific to the `textDocument/formatting`
+ */
+@JsonRpcData
+class FormattingCapabilities extends DynamicRegistrationCapabilities {
+	new() {
+	}
+
+	new(Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+	}
+}
+
+/**
+ * Capabilities specific to the `textDocument/rangeFormatting`
+ */
+@JsonRpcData
+class RangeFormattingCapabilities extends DynamicRegistrationCapabilities {
+	new() {
+	}
+
+	new(Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+	}
+}
+
+/**
+ * Capabilities specific to the `textDocument/onTypeFormatting`
+ */
+@JsonRpcData
+class OnTypeFormattingCapabilities extends DynamicRegistrationCapabilities {
+	new() {
+	}
+
+	new(Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+	}
+}
+
+/**
+ * Capabilities specific to the `textDocument/definition`
+ * <p>
+ * Since 3.14.0
+ */
+@JsonRpcData
+class DefinitionCapabilities extends DynamicRegistrationCapabilities {
+	/**
+	 * The client supports additional metadata in the form of definition links.
+	 */
+	Boolean linkSupport
+
+	new() {
+	}
+
+	new(Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+	}
+
+	new(Boolean dynamicRegistration, Boolean linkSupport) {
+		super(dynamicRegistration)
+		this.linkSupport = linkSupport
+	}
+}
+
+/**
+ * Capabilities specific to the `textDocument/declaration`
+ * <p>
+ * Since 3.14.0
+ */
+@JsonRpcData
+class DeclarationCapabilities extends DynamicRegistrationCapabilities {
+	/**
+	 * The client supports additional metadata in the form of declaration links.
+	 */
+	Boolean linkSupport
+
+	new() {
+	}
+
+	new(Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+	}
+
+	new(Boolean dynamicRegistration, Boolean linkSupport) {
+		super(dynamicRegistration)
+		this.linkSupport = linkSupport
+	}
+}
+
+/**
+ * Capabilities specific to the `textDocument/typeDefinition`
+ * <p>
+ * Since 3.6.0
+ */
+@JsonRpcData
+class TypeDefinitionCapabilities extends DynamicRegistrationCapabilities {
+	/**
+	 * The client supports additional metadata in the form of definition links.
+	 * <p>
+	 * Since 3.14.0
+	 */
+	Boolean linkSupport
+
+	new() {
+	}
+
+	new(Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+	}
+
+	new(Boolean dynamicRegistration, Boolean linkSupport) {
+		super(dynamicRegistration)
+		this.linkSupport = linkSupport
+	}
+}
+
+/**
+ * Capabilities specific to the `textDocument/implementation`.
+ * <p>
+ * Since 3.6.0
+ */
+@JsonRpcData
+class ImplementationCapabilities extends DynamicRegistrationCapabilities {
+	/**
+	 * The client supports additional metadata in the form of definition links.
+	 * <p>
+	 * Since 3.14.0
+	 */
+	Boolean linkSupport
+
+	new() {
+	}
+
+	new(Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+	}
+
+	new(Boolean dynamicRegistration, Boolean linkSupport) {
+		super(dynamicRegistration)
+		this.linkSupport = linkSupport
+	}
+}
+
+@JsonRpcData
+class CodeActionKindCapabilities {
+	/**
+	 * The code action kind values the client supports. When this
+	 * property exists the client also guarantees that it will
+	 * handle values outside its set gracefully and falls back
+	 * to a default value when unknown.
+	 * <p>
+	 * See {@link CodeActionKind} for allowed values.
+	 */
+	@NonNull
+	List<String> valueSet
+
+	new() {
+		this.valueSet = new ArrayList
+	}
+
+	new(@NonNull List<String> valueSet) {
+		this.valueSet = Preconditions.checkNotNull(valueSet, 'valueSet')
+	}
+}
+
+@JsonRpcData
+class CodeActionLiteralSupportCapabilities {
+	/**
+	 * The code action kind is support with the following value
+	 * set.
+	 */
+	CodeActionKindCapabilities codeActionKind
+
+	new() {
+	}
+
+	new(CodeActionKindCapabilities codeActionKind) {
+		this.codeActionKind = codeActionKind
+	}
+}
+
+/**
+ * Whether the client supports resolving additional code action
+ * properties via a separate `codeAction/resolve` request.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class CodeActionResolveSupportCapabilities {
+	/**
+	 * The properties that a client can resolve lazily.
+	 */
+	@NonNull
+	List<String> properties
+
+	new() {
+		this.properties = new ArrayList
+	}
+
+	new(@NonNull List<String> properties) {
+		this.properties = Preconditions.checkNotNull(properties, 'properties')
+	}
+}
+
+/**
+ * Capabilities specific to the `textDocument/codeAction`
+ */
+@JsonRpcData
+class CodeActionCapabilities extends DynamicRegistrationCapabilities {
+	/**
+	 * The client support code action literals as a valid
+	 * response of the `textDocument/codeAction` request.
+	 */
+	CodeActionLiteralSupportCapabilities codeActionLiteralSupport
+
+	/**
+	 * Whether code action supports the {@link CodeAction#isPreferred} property.
+	 * <p>
+	 * Since 3.15.0
+	 */
+	Boolean isPreferredSupport
+
+	/**
+	 * Whether code action supports the {@link CodeAction#disabled} property.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	Boolean disabledSupport
+
+	/**
+	 * Whether code action supports the {@link CodeAction#data} property which is
+	 * preserved between a `textDocument/codeAction` and a
+	 * `codeAction/resolve` request.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	Boolean dataSupport
+
+	/**
+	 * Whether the client supports resolving additional code action
+	 * properties via a separate `codeAction/resolve` request.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	CodeActionResolveSupportCapabilities resolveSupport
+
+	/**
+	 * Whether the client honors the change annotations in
+	 * text edits and resource operations returned via the
+	 * {@link CodeAction#edit} property by for example presenting
+	 * the workspace edit in the user interface and asking
+	 * for confirmation.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	Boolean honorsChangeAnnotations
+
+	new() {
+	}
+
+	new(Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+	}
+
+	new(CodeActionLiteralSupportCapabilities codeActionLiteralSupport, Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+		this.codeActionLiteralSupport = codeActionLiteralSupport
+	}
+
+	new(CodeActionLiteralSupportCapabilities codeActionLiteralSupport, Boolean dynamicRegistration, Boolean isPreferredSupport) {
+		this(codeActionLiteralSupport, dynamicRegistration)
+		this.isPreferredSupport = isPreferredSupport
+	}
+}
+
+/**
+ * Capabilities specific to the `textDocument/codeLens`
+ */
+@JsonRpcData
+class CodeLensCapabilities extends DynamicRegistrationCapabilities {
+	new() {
+	}
+
+	new(Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+	}
+}
+
+/**
+ * Capabilities specific to the code lens requests scoped to the
+ * workspace.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class CodeLensWorkspaceCapabilities {
+
+	/**
+	 * Whether the client implementation supports a refresh request sent from the
+	 * server to the client.
+	 * <p>
+	 * Note that this event is global and will force the client to refresh all
+	 * code lenses currently shown. It should be used with absolute care and is
+	 * useful for situations where a server for example detects a project-wide
+	 * change that requires such a calculation.
+	 */
+	Boolean refreshSupport
+
+	new() {
+	}
+
+	new(Boolean refreshSupport) {
+		this.refreshSupport = refreshSupport
+	}
+}
+
+/**
+ * The client has support for file requests/notifications.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class FileOperationsWorkspaceCapabilities extends DynamicRegistrationCapabilities {
+	/**
+	 * The client has support for sending didCreateFiles notifications.
+	 */
+	Boolean didCreate
+
+	/**
+	 * The client has support for sending willCreateFiles requests.
+	 */
+	Boolean willCreate
+
+	/**
+	 * The client has support for sending didRenameFiles notifications.
+	 */
+	Boolean didRename
+
+	/**
+	 * The client has support for sending willRenameFiles requests.
+	 */
+	Boolean willRename
+
+	/**
+	 * The client has support for sending didDeleteFiles notifications.
+	 */
+	Boolean didDelete
+
+	/**
+	 * The client has support for sending willDeleteFiles requests.
+	 */
+	Boolean willDelete
+
+	new() {
+	}
+}
+
+/**
+ * Capabilities specific to the `textDocument/documentLink`
+ */
+@JsonRpcData
+class DocumentLinkCapabilities extends DynamicRegistrationCapabilities {
+
+	/**
+	 * Whether the client supports the {@link DocumentLink#tooltip} property.
+	 * <p>
+	 * Since 3.15.0
+	 */
+	Boolean tooltipSupport
+
+	new() {
+	}
+
+	new(Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+	}
+
+	new(Boolean dynamicRegistration, Boolean tooltipSupport) {
+		super(dynamicRegistration)
+		this.tooltipSupport = tooltipSupport
+	}
+}
+
+/**
+ * Capabilities specific to the `textDocument/documentColor` and the
+ * `textDocument/colorPresentation` request.
+ * <p>
+ * Since 3.6.0
+ */
+@JsonRpcData
+class ColorProviderCapabilities extends DynamicRegistrationCapabilities {
+	new() {
+	}
+
+	new(Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+	}
+}
+
+/**
+ * Capabilities specific to the `textDocument/rename`
+ */
+@JsonRpcData
+class RenameCapabilities extends DynamicRegistrationCapabilities {
+
+	/**
+	 * Client supports testing for validity of rename operations
+	 * before execution.
+	 * <p>
+	 * Since 3.12.0
+	 */
+	Boolean prepareSupport
+
+	/**
+	 * Client supports the default behavior result ({@code &#123; defaultBehavior: boolean &#125;}).
+	 * <p>
+	 * The value indicates the default behavior used by the client.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	PrepareSupportDefaultBehavior prepareSupportDefaultBehavior
+
+	/**
+	 * Whether the client honors the change annotations in
+	 * text edits and resource operations returned via the
+	 * rename request's workspace edit by for example presenting
+	 * the workspace edit in the user interface and asking
+	 * for confirmation.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	Boolean honorsChangeAnnotations
+
+	new() {
+	}
+
+	new(Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+	}
+
+	new(Boolean prepareSupport, Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+		this.prepareSupport = prepareSupport
+	}
+}
+
+/**
+ * Capabilities specific to `textDocument/publishDiagnostics`.
+ */
+@JsonRpcData
+class PublishDiagnosticsCapabilities {
+	/**
+	 * Whether the client accepts diagnostics with related information.
+	 */
+	Boolean relatedInformation
+
+	/**
+	 * Client supports the tag property to provide meta data about a diagnostic.
+	 * Clients supporting tags have to handle unknown tags gracefully.
+	 * <p>
+	 * This property had been added and implemented as boolean before it was
+	 * added to the specification as {@link DiagnosticsTagSupport}. In order to
+	 * keep this implementation compatible with intermediate clients (including
+	 * vscode-language-client &lt; 6.0.0) we add an either type here.
+	 * <p>
+	 * Since 3.15
+	 */
+	Either<Boolean, DiagnosticsTagSupport> tagSupport
+
+	/**
+	 * Whether the client interprets the version property of the
+	 * `textDocument/publishDiagnostics` notification's parameter.
+	 * <p>
+	 * Since 3.15.0
+	 */
+	Boolean versionSupport
+
+	/**
+	 * Client supports a codeDescription property
+	 * <p>
+	 * Since 3.16.0
+	 */
+	Boolean codeDescriptionSupport
+
+	/**
+	 * Whether code action supports the {@link Diagnostic#data} property which is
+	 * preserved between a `textDocument/publishDiagnostics` and
+	 * `textDocument/codeAction` request.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	Boolean dataSupport
+
+	new() {
+	}
+
+	new(Boolean relatedInformation) {
+		this.relatedInformation = relatedInformation
+	}
+
+	new(Boolean relatedInformation, DiagnosticsTagSupport tagSupport) {
+		this(relatedInformation)
+		this.tagSupport = tagSupport
+	}
+
+	new(Boolean relatedInformation, DiagnosticsTagSupport tagSupport, Boolean versionSupport) {
+		this(relatedInformation, tagSupport)
+		this.versionSupport = versionSupport
+	}
+}
+
+@JsonRpcData
+class DiagnosticsTagSupport {
+	/**
+	* The tags supported by the client.
+	*/
+	@NonNull
+	List<DiagnosticTag> valueSet
+
+	new() {
+		this.valueSet = new ArrayList
+	}
+
+	new(@NonNull List<DiagnosticTag> valueSet) {
+		this.valueSet = Preconditions.checkNotNull(valueSet, 'valueSet')
+	}
+}
+
+/**
+ * Capabilities specific to `textDocument/foldingRange` requests.
+ * <p>
+ * Since 3.10.0
+ */
+@JsonRpcData
+class FoldingRangeCapabilities extends DynamicRegistrationCapabilities {
+	/**
+	 * The maximum number of folding ranges that the client prefers to receive per document. The value serves as a
+	 * hint, servers are free to follow the limit.
+	 */
+	Integer rangeLimit
+
+	/**
+	 * If set, the client signals that it only supports folding complete lines. If set, client will
+	 * ignore specified {@link FoldingRange#startCharacter} and {@link FoldingRange#endCharacter} properties.
+	 */
+	Boolean lineFoldingOnly
+}
+
+/**
+ * Capabilities specific to the {@code textDocument/typeHierarchy}.
+ * <p>
+ * <b>Note:</b> the <a href=
+ * "https://github.com/Microsoft/vscode-languageserver-node/pull/426">{@code textDocument/typeHierarchy}
+ * language feature</a> is not yet part of the official LSP specification.
+ */
+@Beta
+@JsonRpcData
+class TypeHierarchyCapabilities extends DynamicRegistrationCapabilities {
+
+	new() {
+	}
+
+	new(Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+	}
+
+}
+
+/**
+ * Capabilities specific to the {@code textDocument/prepareCallHierarchy}.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class CallHierarchyCapabilities extends DynamicRegistrationCapabilities {
+
+	new() {
+	}
+
+	new(Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+	}
+
+}
+
+/**
+ * Since 3.16.0
+ */
+@JsonRpcData
+class CallHierarchyOptions extends AbstractWorkDoneProgressOptions {
+}
+
+/**
+ * Since 3.16.0
+ */
+@JsonRpcData
+class CallHierarchyRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+	/**
+	 * The id used to register the request. The id can be used to deregister
+	 * the request again. See also Registration#id.
+	 */
+	String id
+
+	new() {
+	}
+
+	new(String id) {
+		this.id = id
+	}
+}
+
+/**
+ * Capabilities specific to `textDocument/selectionRange` requests
+ * <p>
+ * Since 3.15.0
+ */
+@JsonRpcData
+class SelectionRangeCapabilities extends DynamicRegistrationCapabilities {
+
+	new() {
+	}
+
+	new(Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+	}
+}
+
+/**
+ * Since 3.16.0
+ */
+@JsonRpcData
+class SemanticTokensClientCapabilitiesRequestsFull {
+
+	/**
+	* The client will send the `textDocument/semanticTokens/full/delta` request if
+	* the server provides a corresponding handler.
+	*/
+	Boolean delta
+
+	new() {
+	}
+
+	new(Boolean delta) {
+		this.delta = delta
+	}
+}
+
+/**
+ * Since 3.16.0
+ */
+@JsonRpcData
+class SemanticTokensClientCapabilitiesRequests {
+
+	/**
+	* The client will send the `textDocument/semanticTokens/range` request if
+	* the server provides a corresponding handler.
+	*/
+	Either<Boolean, Object> range
+
+	/**
+	* The client will send the `textDocument/semanticTokens/full` request if
+	* the server provides a corresponding handler.
+	*/
+	Either<Boolean, SemanticTokensClientCapabilitiesRequestsFull> full
+
+	new() {
+	}
+
+	new(Boolean full) {
+		this.full = full
+	}
+
+	new(SemanticTokensClientCapabilitiesRequestsFull full) {
+		this.full = full
+	}
+
+	new(Boolean full, Boolean range) {
+		this.full = full
+		this.range = range
+	}
+
+	new(SemanticTokensClientCapabilitiesRequestsFull full, Boolean range) {
+		this.full = full
+		this.range = range
+	}
+
+}
+
+/**
+ * Since 3.16.0
+ */
+@JsonRpcData
+class SemanticTokensCapabilities extends DynamicRegistrationCapabilities {
+
+	/**
+	 * Which requests the client supports and might send to the server.
+	 */
+	@NonNull
+	SemanticTokensClientCapabilitiesRequests requests
+
+	/**
+	 * The token types that the client supports.
+	 */
+	@NonNull
+	List<String> tokenTypes
+
+	/**
+	 * The token modifiers that the client supports.
+	 */
+	@NonNull
+	List<String> tokenModifiers
+
+	/**
+	 * The formats the client supports.
+	 * <p>
+	 * See {@link TokenFormat} for allowed values.
+	 */
+	@NonNull
+	List<String> formats
+
+	/**
+	 * Whether the client supports tokens that can overlap each other.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	Boolean overlappingTokenSupport
+
+	/**
+	 * Whether the client supports tokens that can span multiple lines.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	Boolean multilineTokenSupport
+
+	new(Boolean dynamicRegistration) {
+		super(dynamicRegistration)
+	}
+
+	new(@NonNull SemanticTokensClientCapabilitiesRequests requests, @NonNull List<String> tokenTypes, @NonNull List<String> tokenModifiers, @NonNull List<String> formats) {
+		this.requests = Preconditions.checkNotNull(requests, 'requests')
+		this.tokenTypes = Preconditions.checkNotNull(tokenTypes, 'tokenTypes')
+		this.tokenModifiers = Preconditions.checkNotNull(tokenModifiers, 'tokenModifiers')
+		this.formats = Preconditions.checkNotNull(formats, 'formats')
+	}
+
+
+	new(Boolean dynamicRegistration, @NonNull SemanticTokensClientCapabilitiesRequests requests, @NonNull List<String> tokenTypes, @NonNull List<String> tokenModifiers, @NonNull List<String> formats) {
+		super(dynamicRegistration)
+		this.requests = Preconditions.checkNotNull(requests, 'requests')
+		this.tokenTypes = Preconditions.checkNotNull(tokenTypes, 'tokenTypes')
+		this.tokenModifiers = Preconditions.checkNotNull(tokenModifiers, 'tokenModifiers')
+		this.formats = Preconditions.checkNotNull(formats, 'formats')
+	}
+
+}
+
+/**
+ * Capabilities specific to the {@code textDocument/linkedEditingRange} request.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class LinkedEditingRangeCapabilities extends DynamicRegistrationCapabilities {
+}
+
+/**
+ * Capabilities specific to the semantic token requests scoped to the
+ * workspace.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class SemanticTokensWorkspaceCapabilities {
+	/**
+	 * Whether the client implementation supports a refresh request sent from the
+	 * server to the client.
+	 * <p>
+	 * Note that this event is global and will force the client to refresh all
+	 * semantic tokens currently shown. It should be used with absolute care and is
+	 * useful for situations where a server for example detects a project-wide
+	 * change that requires such a calculation.
+	 */
+	Boolean refreshSupport
+
+	new() {
+	}
+
+	new(Boolean refreshSupport) {
+		this.refreshSupport = refreshSupport
+	}
+}
+
+/**
+ * Capabilities specific to the {@code textDocument/moniker} request.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class MonikerCapabilities extends DynamicRegistrationCapabilities {
+}
+
+/**
+ * Show message request client capabilities
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class WindowShowMessageRequestCapabilities {
+	/**
+	 * Capabilities specific to the {@link MessageActionItem} type.
+	 */
+	WindowShowMessageRequestActionItemCapabilities messageActionItem
+
+	new() {
+	}
+}
+
+/**
+ * Client capabilities for the show document request.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class ShowDocumentCapabilities {
+	/**
+	 * The client has support for the show document
+	 * request.
+	 */
+	boolean support
+
+	new() {
+	}
+
+	new(boolean support) {
+		this.support = support
+	}
+}
+
+/**
+ * Capabilities specific to the {@link MessageActionItem} type of show message request.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class WindowShowMessageRequestActionItemCapabilities {
+	/**
+	 * Whether the client supports additional attributes which
+	 * are preserved and sent back to the server in the
+	 * request's response.
+	 */
+	Boolean additionalPropertiesSupport
+
+	new() {
+	}
+
+	new(Boolean additionalPropertiesSupport) {
+		this.additionalPropertiesSupport = additionalPropertiesSupport
+	}
+}
+
+/**
+ * Client capabilities specific to regular expressions.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class RegularExpressionsCapabilities {
+	/**
+	 * The engine's name.
+	 */
+	@NonNull
+	String engine
+
+	/**
+	 * The engine's version.
+	 */
+	String version
+
+	new() {
+	}
+
+	new(@NonNull String engine) {
+		this.engine = Preconditions.checkNotNull(engine, 'engine')
+	}
+
+	new(@NonNull String engine, String version) {
+		this(engine)
+		this.version = version
+	}
+}
+
+/**
+ * Client capabilities specific to the used markdown parser.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class MarkdownCapabilities {
+	/**
+	 * The name of the parser.
+	 */
+	@NonNull
+	String parser
+
+	/**
+	 * The version of the parser.
+	 */
+	String version
+
+	new() {
+	}
+
+	new(@NonNull String parser) {
+		this.parser = Preconditions.checkNotNull(parser, 'parser')
+	}
+
+	new(@NonNull String parser, String version) {
+		this(parser)
+		this.version = version
+	}
+}
+
+/**
+ * Whether the client in general supports change annotations on text edits,
+ * create file, rename file and delete file changes.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class WorkspaceEditChangeAnnotationSupportCapabilities {
+	/**
+	 * Whether the client groups edits with equal labels into tree nodes,
+	 * for instance all edits labelled with "Changes in Strings" would
+	 * be a tree node.
+	 */
+	Boolean groupsOnLabel
+
+	new() {
+	}
+
+	new(Boolean groupsOnLabel) {
+		this.groupsOnLabel = groupsOnLabel
+	}
+}
+
+
+/**
+ * Text document specific client capabilities.
+ */
+@JsonRpcData
+class TextDocumentClientCapabilities {
+	SynchronizationCapabilities synchronization
+
+	/**
+	 * Capabilities specific to the {@code textDocument/completion}
+	 */
+	CompletionCapabilities completion
+
+	/**
+	 * Capabilities specific to the {@code textDocument/hover}
+	 */
+	HoverCapabilities hover
+
+	/**
+	 * Capabilities specific to the {@code textDocument/signatureHelp}
+	 */
+	SignatureHelpCapabilities signatureHelp
+
+	/**
+	 * Capabilities specific to the {@code textDocument/references}
+	 */
+	ReferencesCapabilities references
+
+	/**
+	 * Capabilities specific to the {@code textDocument/documentHighlight}
+	 */
+	DocumentHighlightCapabilities documentHighlight
+
+	/**
+	 * Capabilities specific to the {@code textDocument/documentSymbol}
+	 */
+	DocumentSymbolCapabilities documentSymbol
+
+	/**
+	 * Capabilities specific to the {@code textDocument/formatting}
+	 */
+	FormattingCapabilities formatting
+
+	/**
+	 * Capabilities specific to the {@code textDocument/rangeFormatting}
+	 */
+	RangeFormattingCapabilities rangeFormatting
+
+	/**
+	 * Capabilities specific to the {@code textDocument/onTypeFormatting}
+	 */
+	OnTypeFormattingCapabilities onTypeFormatting
+
+	/**
+	 * Capabilities specific to the {@code textDocument/declaration}
+	 * <p>
+	 * Since 3.14.0
+	 */
+	DeclarationCapabilities declaration
+
+	/**
+	 * Capabilities specific to the {@code textDocument/definition}
+	 * <p>
+	 * Since 3.14.0
+	 */
+	DefinitionCapabilities definition
+
+	/**
+	 * Capabilities specific to the {@code textDocument/typeDefinition}
+	 * <p>
+	 * Since 3.6.0
+	 */
+	TypeDefinitionCapabilities typeDefinition
+
+	/**
+	 * Capabilities specific to the {@code textDocument/implementation}
+	 * <p>
+	 * Since 3.6.0
+	 */
+	ImplementationCapabilities implementation
+
+	/**
+	 * Capabilities specific to the {@code textDocument/codeAction}
+	 */
+	CodeActionCapabilities codeAction
+
+	/**
+	 * Capabilities specific to the {@code textDocument/codeLens}
+	 */
+	CodeLensCapabilities codeLens
+
+	/**
+	 * Capabilities specific to the {@code textDocument/documentLink}
+	 */
+	DocumentLinkCapabilities documentLink
+
+	/**
+	 * Capabilities specific to the {@code textDocument/documentColor} and the
+	 * {@code textDocument/colorPresentation} request.
+	 * <p>
+	 * Since 3.6.0
+	 */
+	ColorProviderCapabilities colorProvider
+
+	/**
+	 * Capabilities specific to the {@code textDocument/rename}
+	 */
+	RenameCapabilities rename
+
+	/**
+	 * Capabilities specific to {@code textDocument/publishDiagnostics}.
+	 */
+	PublishDiagnosticsCapabilities publishDiagnostics
+
+	/**
+	 * Capabilities specific to {@code textDocument/foldingRange} requests.
+	 * <p>
+	 * Since 3.10.0
+	 */
+	FoldingRangeCapabilities foldingRange
+
+	/**
+	 * Capabilities specific to {@code textDocument/typeHierarchy}.
+	 */
+	@Beta
+	TypeHierarchyCapabilities typeHierarchyCapabilities
+
+	/**
+	 * Capabilities specific to {@code textDocument/prepareCallHierarchy}.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	CallHierarchyCapabilities callHierarchy
+
+	/**
+	 * Capabilities specific to `textDocument/selectionRange` requests
+	 * <p>
+	 * Since 3.15.0
+	 */
+	SelectionRangeCapabilities selectionRange
+
+	/**
+	 * Capabilities specific to {@code textDocument/semanticTokens}.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	SemanticTokensCapabilities semanticTokens
+
+	/**
+	 * Capabilities specific to the {@code textDocument/moniker} request.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	MonikerCapabilities moniker
+
+	/**
+	 * Capabilities specific to the {@code textDocument/linkedEditingRange} request.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	LinkedEditingRangeCapabilities linkedEditingRange
+}
+
+/**
+ * Window specific client capabilities.
+ */
+@JsonRpcData
+class WindowClientCapabilities {
+	/**
+	 * Whether client supports handling progress notifications. If set servers are allowed to
+	 * report in `workDoneProgress` property in the request specific server capabilities.
+	 * <p>
+	 * Since 3.15.0
+	 */
+	Boolean workDoneProgress
+
+	/**
+	 * Capabilities specific to the showMessage request
+	 * <p>
+	 * Since 3.16.0
+	 */
+	WindowShowMessageRequestCapabilities showMessage
+
+	/**
+	 * Client capabilities for the show document request.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	ShowDocumentCapabilities showDocument
+}
+
+/**
+ * General client capabilities.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class GeneralClientCapabilities {
+	/**
+	 * Client capabilities specific to regular expressions.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	RegularExpressionsCapabilities regularExpressions
+
+	/**
+	 * Client capabilities specific to the client's markdown parser.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	MarkdownCapabilities markdown
+}
+
+/**
+ * `ClientCapabilities` now define capabilities for dynamic registration, workspace and text document features the client supports.
+ * The {@link #experimental} can be used to pass experimental capabilities under development.
+ * For future compatibility a `ClientCapabilities` object literal can have more properties set than currently defined.
+ * Servers receiving a `ClientCapabilities` object literal with unknown properties should ignore these properties.
+ * A missing property should be interpreted as an absence of the capability.
+ * If a property is missing that defines sub properties all sub properties should be interpreted as an absence of the capability.
+ * <p>
+ * Client capabilities got introduced with the version 3.0 of the protocol. They therefore only describe capabilities that got introduced in 3.x or later.
+ * Capabilities that existed in the 2.x version of the protocol are still mandatory for clients. Clients cannot opt out of providing them.
+ * So even if a client omits the {@link TextDocumentClientCapabilities#synchronization}
+ * it is still required that the client provides text document synchronization (e.g. open, changed and close notifications).
+ */
+@JsonRpcData
+class ClientCapabilities {
+	/**
+	 * Workspace specific client capabilities.
+	 */
+	WorkspaceClientCapabilities workspace
+
+	/**
+	 * Text document specific client capabilities.
+	 */
+	TextDocumentClientCapabilities textDocument
+
+	/**
+	 * Window specific client capabilities.
+	 */
+	WindowClientCapabilities window
+
+	/**
+	 * General client capabilities.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	GeneralClientCapabilities general
+
+	/**
+	 * Experimental client capabilities.
+	 */
+	@JsonAdapter(JsonElementTypeAdapter.Factory)
+	Object experimental
+
+	new() {
+	}
+
+	new(WorkspaceClientCapabilities workspace, TextDocumentClientCapabilities textDocument, Object experimental) {
+		this.workspace = workspace
+		this.textDocument = textDocument
+		this.experimental = experimental
+	}
+
+	new(WorkspaceClientCapabilities workspace, TextDocumentClientCapabilities textDocument, WindowClientCapabilities window, Object experimental) {
+		this.workspace = workspace
+		this.textDocument = textDocument
+		this.window = window
+		this.experimental = experimental
+	}
+}
+
+/**
+ * A code action represents a change that can be performed in code, e.g. to fix a problem or
+ * to refactor code.
+ * <p>
+ * A CodeAction must set either {@link #edit} and/or a {@link #command}.
+ * If both are supplied, the {@link #edit} is applied first, then the {@link #command} is executed.
+ */
+@JsonRpcData
+class CodeAction {
+	/**
+	 * A short, human-readable, title for this code action.
+	 */
+	@NonNull
+	String title
+
+	/**
+	 * The kind of the code action.
+	 * <p>
+	 * Used to filter code actions.
+	 */
+	String kind
+
+	/**
+	 * The diagnostics that this code action resolves.
+	 */
+	List<Diagnostic> diagnostics
+
+	/**
+	 * Marks this as a preferred action. Preferred actions are used by the `auto fix` command and can be targeted
+	 * by keybindings.
+	 * <p>
+	 * A quick fix should be marked preferred if it properly addresses the underlying error.
+	 * A refactoring should be marked preferred if it is the most reasonable choice of actions to take.
+	 * <p>
+	 * Since 3.15.0
+	 */
+	Boolean isPreferred
+
+	/**
+	 * Marks that the code action cannot currently be applied.
+	 * <p>
+	 * Clients should follow the following guidelines regarding disabled code actions:
+	 * <ul>
+	 * <li>Disabled code actions are not shown in automatic <a href="https://code.visualstudio.com/docs/editor/editingevolved#_code-action">lightbulb</a>
+	 * code action menu.
+	 * <li>Disabled actions are shown as faded out in the code action menu when the user request a more specific type
+	 * of code action, such as refactorings.
+	 * <li>If the user has a <a href="https://code.visualstudio.com/docs/editor/refactoring#_keybindings-for-code-actions">keybinding</a>
+	 * that auto applies a code action and only a disabled code actions are returned, the client should show the user an
+	 * error message with {@link CodeActionDisabled#reason} in the editor.
+	 * </ul><p>
+	 * Since 3.16.0
+	 */
+	CodeActionDisabled disabled
+
+	/**
+	 * The workspace edit this code action performs.
+	 */
+	WorkspaceEdit edit
+
+	/**
+	 * A command this code action executes. If a code action
+	 * provides a edit and a command, first the edit is
+	 * executed and then the command.
+	 */
+	Command command
+
+	/**
+	 * A data entry field that is preserved on a code action between
+	 * a `textDocument/codeAction` and a `codeAction/resolve` request.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	@JsonAdapter(JsonElementTypeAdapter.Factory)
+	Object data
+
+	new() {
+	}
+
+	new(@NonNull String title) {
+		this.title = Preconditions.checkNotNull(title, 'title')
+	}
+}
+
+/**
+ * Marks that the code action cannot currently be applied.
+ * <p>
+ * Clients should follow the following guidelines regarding disabled code actions:
+ * <ul>
+ * <li>Disabled code actions are not shown in automatic <a href="https://code.visualstudio.com/docs/editor/editingevolved#_code-action">lightbulb</a>
+ * code action menu.
+ * <li>Disabled actions are shown as faded out in the code action menu when the user request a more specific type
+ * of code action, such as refactorings.
+ * <li>If the user has a <a href="https://code.visualstudio.com/docs/editor/refactoring#_keybindings-for-code-actions">keybinding</a>
+ * that auto applies a code action and only a disabled code actions are returned, the client should show the user an
+ * error message with {@link #reason} in the editor.
+ * </ul><p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class CodeActionDisabled {
+	/**
+	 * Human readable description of why the code action is currently disabled.
+	 * <p>
+	 * This is displayed in the code actions UI.
+	 */
+	@NonNull
+	String reason
+
+	new() {
+	}
+
+	new(@NonNull String reason) {
+		this.reason = Preconditions.checkNotNull(reason, 'reason')
+	}
+}
+
+/**
+ * Contains additional diagnostic information about the context in which a code action is run.
+ */
+@JsonRpcData
+class CodeActionContext {
+	/**
+	 * An array of diagnostics.
+	 */
+	@NonNull
+	List<Diagnostic> diagnostics
+
+	/**
+	 * Requested kind of actions to return.
+	 * <p>
+	 * Actions not of this kind are filtered out by the client before being shown. So servers
+	 * can omit computing them.
+	 * <p>
+	 * See {@link CodeActionKind} for allowed values.
+	 */
+	List<String> only
+
+	new() {
+	}
+
+	new(@NonNull List<Diagnostic> diagnostics) {
+		this.diagnostics = Preconditions.checkNotNull(diagnostics, 'diagnostics')
+	}
+
+	new(@NonNull List<Diagnostic> diagnostics, List<String> only) {
+		this(diagnostics)
+		this.only = only
+	}
+}
+
+/**
+ * The code action request is sent from the client to the server to compute commands for a given text document and range.
+ * These commands are typically code fixes to either fix problems or to beautify/refactor code.
+ */
+@JsonRpcData
+class CodeActionParams extends WorkDoneProgressAndPartialResultParams {
+	/**
+	 * The document in which the command was invoked.
+	 */
+	@NonNull
+	TextDocumentIdentifier textDocument
+
+	/**
+	 * The range for which the command was invoked.
+	 */
+	@NonNull
+	Range range
+
+	/**
+	 * Context carrying additional information.
+	 */
+	@NonNull
+	CodeActionContext context
+
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument, @NonNull Range range, @NonNull CodeActionContext context) {
+		this.textDocument = Preconditions.checkNotNull(textDocument, 'textDocument')
+		this.range = Preconditions.checkNotNull(range, 'range')
+		this.context = Preconditions.checkNotNull(context, 'context')
+	}
+}
+
+/**
+ * A code lens represents a command that should be shown along with source text, like the number of references,
+ * a way to run tests, etc.
+ * <p>
+ * A code lens is <em>unresolved</em> when no command is associated to it. For performance reasons the creation of a
+ * code lens and resolving should be done to two stages.
+ */
+@JsonRpcData
+class CodeLens {
+	/**
+	 * The range in which this code lens is valid. Should only span a single line.
+	 */
+	@NonNull
+	Range range
+
+	/**
+	 * The command this code lens represents.
+	 */
+	Command command
+
+	/**
+	 * A data entry field that is preserved on a code lens item between a code lens and a code lens resolve request.
+	 */
+	@JsonAdapter(JsonElementTypeAdapter.Factory)
+	Object data
+
+	new() {
+	}
+
+	new(@NonNull Range range) {
+		this.range = Preconditions.checkNotNull(range, 'range')
+	}
+
+	new(@NonNull Range range, Command command, Object data) {
+		this(range)
+		this.command = command
+		this.data = data
+	}
+}
+
+/**
+ * Code Action options.
+ */
+@JsonRpcData
+class CodeActionOptions extends AbstractWorkDoneProgressOptions {
+	/**
+	 * CodeActionKinds that this server may return.
+	 * <p>
+	 * The list of kinds may be generic, such as {@link CodeActionKind#Refactor}, or the server
+	 * may list out every specific kind they provide.
+	 */
+	List<String> codeActionKinds
+
+	/**
+	 * The server provides support to resolve additional
+	 * information for a code action.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	Boolean resolveProvider
+
+	new() {
+	}
+
+	new(List<String> codeActionKinds) {
+		this.codeActionKinds = codeActionKinds
+	}
+}
+
+/**
+ * Code Action registration options.
+ */
+@JsonRpcData
+class CodeActionRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+	/**
+	 * CodeActionKinds that this server may return.
+	 * <p>
+	 * The list of kinds may be generic, such as {@link CodeActionKind#Refactor}, or the server
+	 * may list out every specific kind they provide.
+	 */
+	List<String> codeActionKinds
+
+	/**
+	 * The server provides support to resolve additional
+	 * information for a code action.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	Boolean resolveProvider
+
+	new() {
+	}
+
+	new(List<String> codeActionKinds) {
+		this.codeActionKinds = codeActionKinds
+	}
+}
+
+/**
+ * Code Lens options.
+ */
+@JsonRpcData
+class CodeLensOptions extends AbstractWorkDoneProgressOptions {
+	/**
+	 * Code lens has a resolve provider as well.
+	 */
+	Boolean resolveProvider
+
+	new() {
+	}
+
+	new(Boolean resolveProvider) {
+		this.resolveProvider = resolveProvider
+	}
+}
+
+/**
+ * The code lens request is sent from the client to the server to compute code lenses for a given text document.
+ */
+@JsonRpcData
+class CodeLensParams extends WorkDoneProgressAndPartialResultParams {
+	/**
+	 * The document to request code lens for.
+	 */
+	@NonNull
+	TextDocumentIdentifier textDocument
+
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument) {
+		this.textDocument = Preconditions.checkNotNull(textDocument, 'textDocument')
+	}
+}
+
+/**
+ * Represents a reference to a command. Provides a title which will be used to represent a command in the UI and,
+ * optionally, an array of arguments which will be passed to the command handler function when invoked.
+ */
+@JsonRpcData
+class Command {
+	/**
+	 * Title of the command, like `save`.
+	 */
+	@NonNull
+	String title
+
+	/**
+	 * The identifier of the actual command handler.
+	 */
+	@NonNull
+	String command
+
+	/**
+	 * Arguments that the command handler should be invoked with.
+	 */
+	List<Object> arguments
+
+	new() {
+	}
+
+	new(@NonNull String title, @NonNull String command) {
+		this.title = Preconditions.checkNotNull(title, 'title')
+		this.command = Preconditions.checkNotNull(command, 'command')
+	}
+
+	new(@NonNull String title, @NonNull String command, List<Object> arguments) {
+		this(title, command)
+		this.arguments = arguments
+	}
+}
+
+/**
+ * The Completion request is sent from the client to the server to compute completion items at a given cursor position.
+ * Completion items are presented in the IntelliSense user class. If computing complete completion items is expensive
+ * servers can additional provide a handler for the resolve completion item request. This request is send when a
+ * completion item is selected in the user class.
+ */
+@JsonRpcData
+class CompletionItem {
+	/**
+	 * The label of this completion item. By default also the text that is inserted when selecting this completion.
+	 */
+	@NonNull
+	String label
+
+	/**
+	 * The kind of this completion item. Based of the kind an icon is chosen by the editor.
+	 */
+	CompletionItemKind kind
+
+	/**
+	 * Tags for this completion item.
+	 * <p>
+	 * Since 3.15.0
+	 */
+	List<CompletionItemTag> tags
+
+	/**
+	 * A human-readable string with additional information about this item, like type or symbol information.
+	 */
+	String detail
+
+	/**
+	 * A human-readable string that represents a doc-comment.
+	 */
+	Either<String, MarkupContent> documentation
+
+	/**
+	 * Indicates if this item is deprecated.
+	 *
+	 * @deprecated Use {@link #tags} instead if supported.
+	 */
+	@Deprecated
+	Boolean deprecated
+
+	/**
+	 * Select this item when showing.
+	 * <p>
+	 * <em>Note</em> that only one completion item can be selected and that the
+	 * tool / client decides which item that is. The rule is that the <em>first</em>
+	 * item of those that match best is selected.
+	 */
+	Boolean preselect
+
+	/**
+	 * A string that should be used when comparing this item with other items. When `falsy` the label is used.
+	 */
+	String sortText
+
+	/**
+	 * A string that should be used when filtering a set of completion items. When `falsy` the label is used.
+	 */
+	String filterText
+
+	/**
+	 * A string that should be inserted a document when selecting this completion. When `falsy` the label is used.
+	 */
+	String insertText
+
+	/**
+	 * The format of the insert text. The format applies to both the {@link #insertText} property
+	 * and the {@code newText} property of a provided {@link #textEdit}.
+	 */
+	InsertTextFormat insertTextFormat
+
+	/**
+	 * How whitespace and indentation is handled during completion item
+	 * insertion. If not provided, the client's default value is used.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	InsertTextMode insertTextMode
+
+	/**
+	 * An edit which is applied to a document when selecting this completion.
+	 * When an edit is provided the value of {@link #insertText} is ignored.
+	 * <p>
+	 * <em>Note:</em> The range of the edit must be a single line range and it must
+	 * contain the position at which completion has been requested.
+	 * <p>
+	 * Most editors support two different operations when accepting a completion
+	 * item. One is to insert a completion text and the other is to replace an
+	 * existing text with a completion text. Since this can usually not be
+	 * predetermined by a server it can report both ranges. Clients need to
+	 * signal support for {@link InsertReplaceEdit}s via the
+	 * {@link CompletionItemCapabilities#insertReplaceSupport} client capability
+	 * property.
+	 * <p>
+	 * <em>Note 1:</em> The text edit's range as well as both ranges from an insert
+	 * replace edit must be a [single line] and they must contain the position
+	 * at which completion has been requested.
+	 * <p>
+	 * <em>Note 2:</em> If an {@link InsertReplaceEdit} is returned the edit's insert range
+	 * must be a prefix of the edit's replace range, that means it must be
+	 * contained and starting at the same position.
+	 * <p>
+	 * Since 3.16.0 additional type {@link InsertReplaceEdit}
+	 */
+	@JsonAdapter(CompletionItemTextEditTypeAdapter)
+	Either<TextEdit, InsertReplaceEdit> textEdit
+
+	/**
+	 * An optional array of additional text edits that are applied when
+	 * selecting this completion. Edits must not overlap (including the same insert position)
+	 * with the main edit nor with themselves.
+	 * <p>
+	 * Additional text edits should be used to change text unrelated to the current cursor position
+	 * (for example adding an import statement at the top of the file if the completion item will
+	 * insert an unqualified type).
+	 */
+	List<TextEdit> additionalTextEdits
+
+	/**
+	 * An optional set of characters that when pressed while this completion is active will accept it first and
+	 * then type that character. <em>Note</em> that all commit characters should have {@code length=1} and that superfluous
+	 * characters will be ignored.
+	 */
+	List<String> commitCharacters
+
+	/**
+	 * An optional command that is executed <em>after</em> inserting this completion. <em>Note</em> that
+	 * additional modifications to the current document should be described with the
+	 * {@link #additionalTextEdits} property.
+	 */
+	Command command
+
+	/**
+	 * A data entry field that is preserved on a completion item between a completion and a completion resolve request.
+	 */
+	@JsonAdapter(JsonElementTypeAdapter.Factory)
+	Object data
+
+	new() {
+	}
+
+	new(@NonNull String label) {
+		this.label = Preconditions.checkNotNull(label, 'label')
+	}
+}
+
+/**
+ * Represents a collection of completion items to be presented in the editor.
+ */
+@JsonRpcData
+class CompletionList {
+	/**
+	 * This list it not complete. Further typing should result in recomputing this list.
+	 */
+	boolean isIncomplete
+
+	/**
+	 * The completion items.
+	 */
+	@NonNull
+	List<CompletionItem> items
+
+	new() {
+		this(new ArrayList)
+	}
+
+	new(@NonNull List<CompletionItem> items) {
+		this.items = Preconditions.checkNotNull(items, 'items')
+	}
+
+	new(boolean isIncomplete, @NonNull List<CompletionItem> items) {
+		this(items)
+		this.isIncomplete = isIncomplete
+	}
+}
+
+/**
+ * Completion options.
+ */
+@JsonRpcData
+class CompletionOptions extends AbstractWorkDoneProgressOptions {
+
+	/**
+	 * The server provides support to resolve additional information for a completion item.
+	 */
+	Boolean resolveProvider
+
+	/**
+	 * The characters that trigger completion automatically.
+	 */
+	List<String> triggerCharacters
+
+	/**
+	 * The list of all possible characters that commit a completion. This field
+	 * can be used if clients don't support individual commit characters per
+	 * completion item. See client capability
+	 * {@link CompletionItemCapabilities#commitCharactersSupport}.
+	 * <p>
+	 * If a server provides both {@code allCommitCharacters} and commit characters on
+	 * an individual completion item the ones on the completion item win.
+	 * <p>
+	 * Since 3.2.0
+	 */
+	List<String> allCommitCharacters
+
+	new() {
+	}
+
+	new(Boolean resolveProvider, List<String> triggerCharacters) {
+		this.resolveProvider = resolveProvider
+		this.triggerCharacters = triggerCharacters
+	}
+}
+
+/**
+ * Represents a diagnostic, such as a compiler error or warning. Diagnostic objects are only valid in the scope of a resource.
+ */
+@JsonRpcData
+class Diagnostic {
+	/**
+	 * The range at which the message applies
+	 */
+	@NonNull
+	Range range
+
+	/**
+	 * The diagnostic's severity. Can be omitted. If omitted it is up to the client to interpret diagnostics as error,
+	 * warning, info or hint.
+	 */
+	DiagnosticSeverity severity
+
+	/**
+	 * The diagnostic's code. Can be omitted.
+	 */
+	Either<String, Integer> code
+
+	/**
+	 * An optional property to describe the error code.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	DiagnosticCodeDescription codeDescription
+
+	/**
+	 * A human-readable string describing the source of this diagnostic, e.g. 'typescript' or 'super lint'.
+	 */
+	String source
+
+	/**
+	 * The diagnostic's message.
+	 */
+	@NonNull
+	String message
+
+	/**
+	 * Additional metadata about the diagnostic.
+	 * <p>
+	 * Since 3.15.0
+	 */
+	 List<DiagnosticTag> tags
+
+	/**
+	 * An array of related diagnostic information, e.g. when symbol-names within a scope collide
+	 * all definitions can be marked via this property.
+	 * <p>
+	 * Since 3.7.0
+	 */
+	List<DiagnosticRelatedInformation> relatedInformation
+
+	/**
+	 * A data entry field that is preserved between a `textDocument/publishDiagnostics`
+	 * notification and `textDocument/codeAction` request.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	@JsonAdapter(JsonElementTypeAdapter.Factory)
+	Object data
+
+	new() {
+	}
+
+	new(@NonNull Range range, @NonNull String message) {
+		this.range = Preconditions.checkNotNull(range, 'range')
+		this.message = Preconditions.checkNotNull(message, 'message')
+	}
+
+	new(@NonNull Range range, @NonNull String message, DiagnosticSeverity severity, String source) {
+		this(range, message)
+		this.severity = severity
+		this.source = source
+	}
+
+	new(@NonNull Range range, @NonNull String message, DiagnosticSeverity severity, String source, String code) {
+		this(range, message, severity, source)
+		this.code = code
+	}
+}
+
+/**
+ * Represents a related message and source code location for a diagnostic. This should be
+ * used to point to code locations that cause or related to a diagnostics, e.g when duplicating
+ * a symbol in a scope.
+ * <p>
+ * Since 3.7.0
+ */
+@JsonRpcData
+class DiagnosticRelatedInformation {
+	/**
+	 * The location of this related diagnostic information.
+	 */
+	@NonNull
+	Location location
+
+	/**
+	 * The message of this related diagnostic information.
+	 */
+	@NonNull
+	String message
+
+	new() {
+	}
+
+	new(@NonNull Location location, @NonNull String message) {
+		this.location = Preconditions.checkNotNull(location, 'location')
+		this.message = Preconditions.checkNotNull(message, 'message')
+	}
+}
+
+/**
+ * Structure to capture a description for an error code.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class DiagnosticCodeDescription {
+	/**
+	 * A URI to open with more information about the diagnostic error.
+	 */
+	@NonNull
+	String href
+
+	new() {
+	}
+
+	new(@NonNull String href) {
+		this.href = Preconditions.checkNotNull(href, 'href')
+	}
+}
+
+/**
+ * A notification sent from the client to the server to signal the change of configuration settings.
+ */
+@JsonRpcData
+class DidChangeConfigurationParams {
+	/**
+	 * The actual changed settings.
+	 */
+	@NonNull
+	@JsonAdapter(JsonElementTypeAdapter.Factory)
+	Object settings
+
+	new() {
+	}
+
+	new(@NonNull Object settings) {
+		this.settings = Preconditions.checkNotNull(settings, 'settings')
+	}
+}
+
+/**
+ * The document change notification is sent from the client to the server to signal changes to a text document.
+ */
+@JsonRpcData
+class DidChangeTextDocumentParams {
+	/**
+	 * The document that did change. The version number points to the version after all provided content changes have
+	 * been applied.
+	 */
+	@NonNull
+	VersionedTextDocumentIdentifier textDocument
+
+	/**
+	 * Legacy property to support protocol version 1.0 requests.
+	 */
+	@Deprecated
+	String uri
+
+	/**
+	 * The actual content changes.
+	 */
+	@NonNull
+	List<TextDocumentContentChangeEvent> contentChanges = new ArrayList
+
+	new() {
+	}
+
+	new(@NonNull VersionedTextDocumentIdentifier textDocument,
+		@NonNull List<TextDocumentContentChangeEvent> contentChanges) {
+		this.textDocument = Preconditions.checkNotNull(textDocument, 'textDocument')
+		this.contentChanges = Preconditions.checkNotNull(contentChanges, 'contentChanges')
+	}
+
+	@Deprecated
+	new(@NonNull VersionedTextDocumentIdentifier textDocument, String uri,
+		@NonNull List<TextDocumentContentChangeEvent> contentChanges) {
+		this(textDocument, contentChanges)
+		this.uri = uri
+	}
+}
+
+/**
+ * The watched files notification is sent from the client to the server when the client detects changes
+ * to file watched by the language client.
+ */
+@JsonRpcData
+class DidChangeWatchedFilesParams {
+	/**
+	 * The actual file events.
+	 */
+	@NonNull
+	List<FileEvent> changes
+
+	new() {
+		this(new ArrayList)
+	}
+
+	new(@NonNull List<FileEvent> changes) {
+		this.changes = Preconditions.checkNotNull(changes, 'changes')
+	}
+}
+
+@JsonRpcData
+class DidChangeWatchedFilesRegistrationOptions {
+	/**
+	 * The watchers to register.
+	 */
+	@NonNull
+	List<FileSystemWatcher> watchers
+
+	new() {
+	}
+
+	new(@NonNull List<FileSystemWatcher> watchers) {
+		this.watchers = Preconditions.checkNotNull(watchers, 'watchers')
+	}
+}
+
+@JsonRpcData
+class FileSystemWatcher {
+	/**
+	 * The glob pattern to watch
+	 */
+	@NonNull
+	String globPattern
+
+	/**
+	 * The kind of events of interest. If omitted it defaults
+	 * to WatchKind.Create | WatchKind.Change | WatchKind.Delete
+	 * which is 7.
+	 */
+	Integer kind
+
+	new() {
+	}
+
+	new(@NonNull String globPattern) {
+		this.globPattern = Preconditions.checkNotNull(globPattern, 'globPattern')
+	}
+
+	new(@NonNull String globPattern, Integer kind) {
+		this(globPattern)
+		this.kind = kind
+	}
+}
+
+/**
+ * The document close notification is sent from the client to the server when the document got closed in the client.
+ * The document's truth now exists where the document's uri points to (e.g. if the document's uri is a file uri the
+ * truth now exists on disk).
+ */
+@JsonRpcData
+class DidCloseTextDocumentParams {
+	/**
+	 * The document that was closed.
+	 */
+	@NonNull
+	TextDocumentIdentifier textDocument
+
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument) {
+		this.textDocument = Preconditions.checkNotNull(textDocument, 'textDocument')
+	}
+}
+
+/**
+ * The document open notification is sent from the client to the server to signal newly opened text documents.
+ * The document's truth is now managed by the client and the server must not try to read the document's truth using
+ * the document's uri.
+ */
+@JsonRpcData
+class DidOpenTextDocumentParams {
+	/**
+	 * The document that was opened.
+	 */
+	@NonNull
+	TextDocumentItem textDocument
+
+	/**
+	 * Legacy property to support protocol version 1.0 requests.
+	 */
+	@Deprecated
+	String text
+
+	new() {
+	}
+
+	new(@NonNull TextDocumentItem textDocument) {
+		this.textDocument = Preconditions.checkNotNull(textDocument, 'textDocument')
+	}
+
+	@Deprecated
+	new(@NonNull TextDocumentItem textDocument, String text) {
+		this(textDocument)
+		this.text = text
+	}
+}
+
+/**
+ * The document save notification is sent from the client to the server when the document was saved in the client.
+ */
+@JsonRpcData
+class DidSaveTextDocumentParams {
+	/**
+	 * The document that was closed.
+	 */
+	@NonNull
+	TextDocumentIdentifier textDocument
+
+	/**
+	 * Optional the content when saved. Depends on the includeText value
+	 * when the save notification was requested.
+	 */
+	String text
+
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument) {
+		this.textDocument = Preconditions.checkNotNull(textDocument, 'textDocument')
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument, String text) {
+		this(textDocument)
+		this.text = text
+	}
+}
+
+@JsonRpcData
+class WillSaveTextDocumentParams {
+	/**
+	 * The document that will be saved.
+	 */
+	@NonNull
+	TextDocumentIdentifier textDocument
+
+	/**
+	 * A reason why a text document is saved.
+	 */
+	@NonNull
+	TextDocumentSaveReason reason
+
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument, @NonNull TextDocumentSaveReason reason) {
+		this.textDocument = Preconditions.checkNotNull(textDocument, 'textDocument')
+		this.reason = Preconditions.checkNotNull(reason, 'reason')
+	}
+}
+
+/**
+ * The document formatting request is sent from the server to the client to format a whole document.
+ */
+@JsonRpcData
+class DocumentFormattingParams implements WorkDoneProgressParams {
+	/**
+	 * An optional token that a server can use to report work done progress.
+	 */
+	Either<String, Integer> workDoneToken
+
+	/**
+	 * The document to format.
+	 */
+	@NonNull
+	TextDocumentIdentifier textDocument
+
+	/**
+	 * The format options
+	 */
+	@NonNull
+	FormattingOptions options
+
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument, @NonNull FormattingOptions options) {
+		this.textDocument = Preconditions.checkNotNull(textDocument, 'textDocument')
+		this.options = Preconditions.checkNotNull(options, 'options')
+	}
+}
+
+/**
+ * Document formatting options.
+ */
+@JsonRpcData
+class DocumentFormattingOptions extends AbstractWorkDoneProgressOptions {
+}
+
+/**
+ * Document formatting registration options.
+ */
+@JsonRpcData
+class DocumentFormattingRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+}
+
+/**
+ * A document highlight is a range inside a text document which deserves special attention. Usually a document highlight
+ * is visualized by changing the background color of its range.
+ */
+@JsonRpcData
+class DocumentHighlight {
+	/**
+	 * The range this highlight applies to.
+	 */
+	@NonNull
+	Range range
+
+	/**
+	 * The highlight kind, default is {@link DocumentHighlightKind#Text}.
+	 */
+	DocumentHighlightKind kind
+
+	new() {
+	}
+
+	new(@NonNull Range range) {
+		this.range = Preconditions.checkNotNull(range, 'range')
+	}
+
+	new(@NonNull Range range, DocumentHighlightKind kind) {
+		this(range)
+		this.kind = kind
+	}
+}
+
+/**
+ * A document link is a range in a text document that links to an internal or external resource, like another
+ * text document or a web site.
+ */
+@JsonRpcData
+class DocumentLink {
+	/**
+	 * The range this link applies to.
+	 */
+	@NonNull
+	Range range
+
+	/**
+	 * The uri this link points to. If missing a resolve request is sent later.
+	 */
+	String target
+
+	/**
+	 * The tooltip text when you hover over this link.
+	 * <p>
+	 * If a tooltip is provided, is will be displayed in a string that includes instructions on how to
+	 * trigger the link, such as `{0} (ctrl + click)`. The specific instructions vary depending on OS,
+	 * user settings, and localization.
+	 * <p>
+	 * Since 3.15.0
+	 */
+	String tooltip
+
+	/**
+	 * A data entry field that is preserved on a document link between a
+	 * DocumentLinkRequest and a DocumentLinkResolveRequest.
+	 */
+	@JsonAdapter(JsonElementTypeAdapter.Factory)
+	Object data
+
+	new() {
+	}
+
+	new(@NonNull Range range) {
+		this.range = Preconditions.checkNotNull(range, 'range')
+	}
+
+	new(@NonNull Range range, String target) {
+		this(range)
+		this.target = target
+	}
+
+	new(@NonNull Range range, String target, Object data) {
+		this(range, target)
+		this.data = data
+	}
+
+	new(@NonNull Range range, String target, Object data, String tooltip) {
+		this(range, target, data)
+		this.tooltip = tooltip
+	}
+}
+
+/**
+ * The document links request is sent from the client to the server to request the location of links in a document.
+ */
+@JsonRpcData
+class DocumentLinkParams extends WorkDoneProgressAndPartialResultParams {
+	/**
+	 * The document to provide document links for.
+	 */
+	@NonNull
+	TextDocumentIdentifier textDocument
+
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument) {
+		this.textDocument = Preconditions.checkNotNull(textDocument, 'textDocument')
+	}
+}
+
+/**
+ * Document link options
+ */
+@JsonRpcData
+class DocumentLinkOptions extends AbstractWorkDoneProgressOptions {
+	/**
+	 * Document links have a resolve provider as well.
+	 */
+	Boolean resolveProvider
+
+	new() {
+	}
+
+	new(Boolean resolveProvider) {
+		this.resolveProvider = resolveProvider
+	}
+}
+
+/**
+ * Execute command options.
+ */
+@JsonRpcData
+class ExecuteCommandOptions extends AbstractWorkDoneProgressOptions {
+
+	/**
+	 * The commands to be executed on the server
+	 */
+	@NonNull
+	List<String> commands
+
+	new() {
+		this(new ArrayList)
+	}
+
+	new(@NonNull List<String> commands) {
+		this.commands = Preconditions.checkNotNull(commands, 'commands')
+	}
+}
+
+/**
+ * Save options.
+ */
+@JsonRpcData
+class SaveOptions {
+	/**
+	 * The client is supposed to include the content on save.
+	 */
+	Boolean includeText
+
+	new() {
+	}
+
+	new(Boolean includeText) {
+		this.includeText = includeText
+	}
+}
+
+/**
+ * Rename options
+ */
+@JsonRpcData
+class RenameOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+	/**
+	 * The id used to register the request. The id can be used to deregister
+	 * the request again. See also Registration#id.
+	 *
+	 * @deprecated This options object is not specified for StaticRegistrationOptions
+	 */
+	@Deprecated
+	String id
+
+	/**
+	 * Renames should be checked and tested before being executed.
+	 */
+	Boolean prepareProvider
+
+	new() {
+	}
+
+	@Deprecated
+	new(String id) {
+		this.id = id
+	}
+
+	new(Boolean prepareProvider) {
+		this.prepareProvider = prepareProvider
+	}
+}
+
+/**
+ * Document color options
+ */
+@JsonRpcData
+class ColorProviderOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+	/**
+	 * The id used to register the request. The id can be used to deregister
+	 * the request again. See also Registration#id.
+	 */
+	String id
+
+	new() {
+	}
+
+	new(String id) {
+		this.id = id
+	}
+}
+
+/**
+ * Folding range options.
+ */
+@JsonRpcData
+class FoldingRangeProviderOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+	/**
+	 * The id used to register the request. The id can be used to deregister
+	 * the request again. See also Registration#id.
+	 */
+	String id
+
+	new() {
+	}
+
+	new(String id) {
+		this.id = id
+	}
+}
+
+@JsonRpcData
+class TextDocumentSyncOptions {
+	/**
+	 * Open and close notifications are sent to the server.
+	 */
+	Boolean openClose
+	/**
+	 * Change notifications are sent to the server. See TextDocumentSyncKind.None, TextDocumentSyncKind.Full
+	 * and TextDocumentSyncKind.Incremental.
+	 */
+	TextDocumentSyncKind change
+	/**
+	 * Will save notifications are sent to the server.
+	 */
+	Boolean willSave
+	/**
+	 * Will save wait until requests are sent to the server.
+	 */
+	Boolean willSaveWaitUntil
+	/**
+	 * Save notifications are sent to the server.
+	 */
+	Either<Boolean, SaveOptions> save
+}
+
+/**
+ * Static registration options to be returned in the initialize request.
+ */
+@JsonRpcData
+class StaticRegistrationOptions extends TextDocumentRegistrationOptions {
+	/**
+	 * The id used to register the request. The id can be used to deregister
+	 * the request again. See also Registration#id.
+	 */
+	String id
+
+	new() {
+	}
+
+	new(String id) {
+		this.id = id
+	}
+}
+
+/**
+ * Format document on type options
+ */
+@JsonRpcData
+class DocumentOnTypeFormattingOptions {
+	/**
+	 * A character on which formatting should be triggered, like `}`.
+	 */
+	@NonNull
+	String firstTriggerCharacter
+
+	/**
+	 * More trigger characters.
+	 */
+	List<String> moreTriggerCharacter
+
+	new() {
+	}
+
+	new(@NonNull String firstTriggerCharacter) {
+		this.firstTriggerCharacter = firstTriggerCharacter
+	}
+
+	new(@NonNull String firstTriggerCharacter, List<String> moreTriggerCharacter) {
+		this.firstTriggerCharacter = Preconditions.checkNotNull(firstTriggerCharacter, 'firstTriggerCharacter')
+		this.moreTriggerCharacter = moreTriggerCharacter
+	}
+}
+
+/**
+ * The document on type formatting request is sent from the client to the server to format parts of the document during typing.
+ */
+@JsonRpcData
+class DocumentOnTypeFormattingParams extends TextDocumentPositionParams {
+	/**
+	 * The format options
+	 */
+	@NonNull
+	FormattingOptions options
+
+	/**
+	 * The character that has been typed.
+	 */
+	@NonNull
+	String ch
+
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument, @NonNull FormattingOptions options, @NonNull Position position, @NonNull String ch) {
+		super(textDocument, position)
+		this.options = Preconditions.checkNotNull(options, 'options')
+		this.ch = Preconditions.checkNotNull(ch, 'ch')
+	}
+
+	@Deprecated
+	new(@NonNull Position position, @NonNull String ch) {
+		super.setPosition(position)
+		this.ch = Preconditions.checkNotNull(ch, 'ch')
+	}
+}
+
+/**
+ * The document range formatting request is sent from the client to the server to format a given range in a document.
+ */
+@JsonRpcData
+class DocumentRangeFormattingParams implements WorkDoneProgressParams {
+	/**
+	 * An optional token that a server can use to report work done progress.
+	 */
+	Either<String, Integer> workDoneToken
+
+	/**
+	 * The document to format.
+	 */
+	@NonNull
+	TextDocumentIdentifier textDocument
+
+	/**
+	 * The format options
+	 */
+	@NonNull
+	FormattingOptions options
+
+	/**
+	 * The range to format
+	 */
+	@NonNull
+	Range range
+
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument, @NonNull FormattingOptions options, @NonNull Range range) {
+		this.textDocument = Preconditions.checkNotNull(textDocument, 'textDocument')
+		this.options = Preconditions.checkNotNull(options, 'options')
+		this.range = Preconditions.checkNotNull(range, 'range')
+	}
+
+	@Deprecated
+	new(@NonNull Range range) {
+		this.range = Preconditions.checkNotNull(range, 'range')
+	}
+}
+
+/**
+ * Document range formatting options.
+ */
+@JsonRpcData
+class DocumentRangeFormattingOptions extends AbstractWorkDoneProgressOptions {
+}
+
+/**
+ * Document range formatting registration options.
+ */
+@JsonRpcData
+class DocumentRangeFormattingRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+}
+
+/**
+ * The type hierarchy request is sent from the client resolve a {@link TypeHierarchyItem type hierarchy item} for
+ * a give cursor location in the text document. The request would also allow to specify if the item should be resolved
+ * and whether sub- or supertypes are to be resolved.
+ */
+@Beta
+@JsonRpcData
+class TypeHierarchyParams extends TextDocumentPositionParams {
+	/**
+	 * The number of hierarchy levels to resolve. {@code 0} indicates no hierarchy level. It defaults to {@code 0}.
+	 */
+	int resolve
+
+	/**
+	 * The direction of the type hierarchy resolution. If not defined, defaults to {@link TypeHierarchyDirection#Children Children}.
+	 */
+	TypeHierarchyDirection direction
+}
+
+/**
+ * Request to resolve an unresolved {@link TypeHierarchyItem type hierarchy item} which is indicated if the
+ * {@link TypeHierarchyItem#getParents parents} or the {@link TypeHierarchyItem#getChildren children} is not
+ * defined. If resolved and no {@code parents} or {@code children} are available then an empty list is returned.
+ */
+@Beta
+@JsonRpcData
+class ResolveTypeHierarchyItemParams {
+	/**
+	 * The hierarchy item to resolve.
+	 */
+	@NonNull
+	TypeHierarchyItem item
+
+	/**
+	 * The number of hierarchy levels to resolve. {@code 0} indicates no hierarchy level.
+	 */
+	int resolve
+
+	/**
+	 * The direction of the type hierarchy resolution.
+	 */
+	@NonNull
+	TypeHierarchyDirection direction
+
+	new() {
+	}
+
+	new(@NonNull TypeHierarchyItem item, int resolve, @NonNull TypeHierarchyDirection direction) {
+		this.item = Preconditions.checkNotNull(item, 'item')
+		this.resolve = resolve
+		this.direction = Preconditions.checkNotNull(direction, 'direction')
+	}
+}
+
+@JsonRpcData
+class DocumentSymbolOptions extends AbstractWorkDoneProgressOptions {
+	/**
+	 * A human-readable string that is shown when multiple outlines trees
+	 * are shown for the same document.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	String label
+
+	new() {
+	}
+
+	new(String label) {
+		this.label = label
+	}
+}
+
+@JsonRpcData
+class DocumentSymbolRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+	/**
+	 * A human-readable string that is shown when multiple outlines trees
+	 * are shown for the same document.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	String label
+
+	new() {
+	}
+
+	new(String label) {
+		this.label = label
+	}
+}
+
+/**
+ * The document symbol request is sent from the client to the server to list all symbols found in a given text document.
+ */
+@JsonRpcData
+class DocumentSymbolParams extends WorkDoneProgressAndPartialResultParams {
+	/**
+	 * The text document.
+	 */
+	@NonNull
+	TextDocumentIdentifier textDocument
+
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument) {
+		this.textDocument = Preconditions.checkNotNull(textDocument, 'textDocument')
+	}
+}
+
+/**
+ * An event describing a file change.
+ */
+@JsonRpcData
+class FileEvent {
+	/**
+	 * The file's uri.
+	 */
+	@NonNull
+	String uri
+
+	/**
+	 * The change type.
+	 */
+	@NonNull
+	FileChangeType type
+
+	new() {
+	}
+
+	new(@NonNull String uri, @NonNull FileChangeType type) {
+		this.uri = Preconditions.checkNotNull(uri, 'uri')
+		this.type = Preconditions.checkNotNull(type, 'type')
+	}
+}
+
+/**
+ * Value-object describing what options formatting should use.
+ */
+class FormattingOptions extends LinkedHashMap<String, Either3<String, Number, Boolean>> {
+
+	static val TAB_SIZE = 'tabSize'
+	static val INSERT_SPACES = 'insertSpaces'
+	static val TRIM_TRAILING_WHITESPACE = 'trimTrailingWhitespace'
+	static val INSERT_FINAL_NEWLINE = 'insertFinalNewline'
+	static val TRIM_FINAL_NEWLINES = 'trimFinalNewlines'
+
+	new() {
+	}
+
+	new(int tabSize, boolean insertSpaces) {
+		this.tabSize = tabSize
+		this.insertSpaces = insertSpaces
+	}
+
+	/**
+	 * @deprecated See https://github.com/eclipse/lsp4j/issues/99
+	 */
+	@Deprecated
+	new(int tabSize, boolean insertSpaces, Map<String, String> properties) {
+		this(tabSize, insertSpaces)
+		setProperties(properties)
+	}
+
+	def String getString(String key) {
+		get(key)?.getFirst
+	}
+
+	def void putString(String key, String value) {
+		put(key, Either3.forFirst(value))
+	}
+
+	def Number getNumber(String key) {
+		get(key)?.getSecond
+	}
+
+	def void putNumber(String key, Number value) {
+		put(key, Either3.forSecond(value))
+	}
+
+	def Boolean getBoolean(String key) {
+		get(key)?.getThird
+	}
+
+	def void putBoolean(String key, Boolean value) {
+		put(key, Either3.forThird(value))
+	}
+
+	/**
+	 * Size of a tab in spaces.
+	 */
+	def int getTabSize() {
+		val value = getNumber(TAB_SIZE)
+		if (value !== null)
+			return value.intValue
+		else
+			return 0
+	}
+
+	def void setTabSize(int tabSize) {
+		putNumber(TAB_SIZE, tabSize)
+	}
+
+	/**
+	 * Prefer spaces over tabs.
+	 */
+	def boolean isInsertSpaces() {
+		val value = getBoolean(INSERT_SPACES)
+		if (value !== null)
+			return value
+		else
+			return false
+	}
+
+	def void setInsertSpaces(boolean insertSpaces) {
+		putBoolean(INSERT_SPACES, insertSpaces)
+	}
+
+	/**
+	 * Trim trailing whitespace on a line.
+	 * <p>
+	 * Since 3.15.0
+	 */
+	def boolean isTrimTrailingWhitespace() {
+		val value = getBoolean(TRIM_TRAILING_WHITESPACE)
+		if (value !== null)
+			return value
+		else
+			return false
+	}
+
+	def void setTrimTrailingWhitespace(boolean trimTrailingWhitespace) {
+		putBoolean(TRIM_TRAILING_WHITESPACE, trimTrailingWhitespace)
+	}
+
+	/**
+	 * Insert a newline character at the end of the file if one does not exist.
+	 * <p>
+	 * Since 3.15.0
+	 */
+	def boolean isInsertFinalNewline() {
+		val value = getBoolean(INSERT_FINAL_NEWLINE)
+		if (value !== null)
+			return value
+		else
+			return false
+	}
+
+	def void setInsertFinalNewline(boolean insertFinalNewline) {
+		putBoolean(INSERT_FINAL_NEWLINE, insertFinalNewline)
+	}
+
+	/**
+	 * Trim all newlines after the final newline at the end of the file.
+	 * <p>
+	 * Since 3.15.0
+	 */
+	def boolean isTrimFinalNewlines() {
+		val value = getBoolean(TRIM_FINAL_NEWLINES)
+		if (value !== null)
+			return value
+		else
+			return false
+	}
+
+	def void setTrimFinalNewlines(boolean trimFinalNewlines) {
+		putBoolean(TRIM_FINAL_NEWLINES, trimFinalNewlines)
+	}
+
+	/**
+	 * @deprecated See https://github.com/eclipse/lsp4j/issues/99
+	 */
+	@Deprecated
+	def Map<String, String> getProperties() {
+		val properties = newLinkedHashMap
+		for (entry : entrySet) {
+			val value = switch it: entry.value {
+				case isFirst: getFirst
+				case isSecond: getSecond
+				case isThird: getThird
+			}
+			if (value !== null)
+				properties.put(entry.key, value.toString)
+		}
+		return properties.unmodifiableView
+	}
+
+	/**
+	 * @deprecated See https://github.com/eclipse/lsp4j/issues/99
+	 */
+	@Deprecated
+	def void setProperties(Map<String, String> properties) {
+		for (entry : properties.entrySet) {
+			putString(entry.key, entry.value)
+		}
+	}
+
+}
+
+/**
+ * A MarkupContent literal represents a string value which content is interpreted based on its
+ * kind flag. Currently the protocol supports {@link MarkupKind#PLAINTEXT plaintext} and
+ * {@link MarkupKind#MARKDOWN markdown} as markup kinds.
+ * <p>
+ * If the kind is {@link MarkupKind#MARKDOWN markdown} then the value can contain fenced code blocks like in GitHub issues.
+ * See https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting
+ * <p>
+ * Please Note that clients might sanitize the return markdown. A client could decide to
+ * remove HTML from the markdown to avoid script execution.
+ */
+@JsonRpcData
+class MarkupContent {
+	/**
+	 * The type of the Markup.
+	 */
+	@NonNull
+	String kind
+
+	/**
+	 * The content itself.
+	 */
+	@NonNull
+	String value
+
+	new() {
+	}
+
+	new(@NonNull String kind, @NonNull String value) {
+		this.kind = Preconditions.checkNotNull(kind, 'kind')
+		this.value = Preconditions.checkNotNull(value, 'value')
+	}
+}
+
+/**
+ * The result of a hover request.
+ */
+@JsonRpcData
+@JsonAdapter(HoverTypeAdapter.Factory)
+class Hover {
+	/**
+	 * The hover's content as markdown
+	 */
+	@NonNull
+	Either<List<Either<String, MarkedString>>, MarkupContent> contents
+
+	/**
+	 * An optional range
+	 */
+	Range range
+
+	new() {
+	}
+
+	new(@NonNull List<Either<String, MarkedString>> contents) {
+		this.contents = Preconditions.checkNotNull(contents, 'contents')
+	}
+
+	new(@NonNull List<Either<String, MarkedString>> contents, Range range) {
+		this.contents = Preconditions.checkNotNull(contents, 'contents')
+		this.range = range
+	}
+
+	new(@NonNull MarkupContent contents) {
+		this.contents = Preconditions.checkNotNull(contents, 'contents')
+	}
+
+	new(@NonNull MarkupContent contents, Range range) {
+		this.contents = Preconditions.checkNotNull(contents, 'contents')
+		this.range = range
+	}
+
+	new(@NonNull Either<String, MarkedString> contents) {
+		this.contents = Arrays.asList(Preconditions.checkNotNull(contents, 'contents'))
+	}
+}
+
+/**
+ * MarkedString can be used to render human readable text. It is either a markdown string
+ * or a code-block that provides a language and a code snippet. The language identifier
+ * is semantically equal to the optional language identifier in fenced code blocks in GitHub
+ * issues. See https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting
+ * <p>
+ * The pair of a language and a value is an equivalent to markdown:
+ * <pre>
+ * ```${language}
+ * ${value}
+ * ```
+ * </pre>
+ * <p>
+ * Note that markdown strings will be sanitized - that means html will be escaped.
+ *
+ * @deprecated Use {@link MarkupContent} instead.
+ */
+@JsonRpcData
+@Deprecated
+class MarkedString {
+	@NonNull
+	String language
+
+	@NonNull
+	String value
+
+	new() {
+	}
+
+	new(@NonNull String language, @NonNull String value) {
+		this.language = Preconditions.checkNotNull(language, 'language')
+		this.value = Preconditions.checkNotNull(value, 'value')
+	}
+}
+
+/**
+ * The $/progress notification payload interface.
+ * <p>
+ * Since 3.15.0
+ */
+interface WorkDoneProgressNotification {
+	def WorkDoneProgressKind getKind()
+}
+
+/**
+ * The $/progress notification payload to start progress reporting.
+ * <p>
+ * Since 3.15.0
+ */
+@JsonRpcData
+class WorkDoneProgressBegin implements WorkDoneProgressNotification {
+
+	/**
+	 * Always return begin
+	 */
+	override WorkDoneProgressKind getKind() {
+		WorkDoneProgressKind.begin
+	}
+
+	/**
+	 * Mandatory title of the progress operation. Used to briefly inform about
+	 * the kind of operation being performed.
+	 * <p>
+	 * Examples: "Indexing" or "Linking dependencies".
+	 */
+	@NonNull
+	String title
+
+	/**
+	 * Controls if a cancel button should show to allow the user to cancel the
+	 * long running operation. Clients that don't support cancellation are allowed
+	 * to ignore the setting.
+	 */
+	Boolean cancellable
+
+	/**
+	 * Optional, more detailed associated progress message. Contains
+	 * complementary information to the {@link #title}.
+	 * <p>
+	 * Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
+	 * If unset, the previous progress message (if any) is still valid.
+	 */
+	String message
+
+	/**
+	 * Optional progress percentage to display (value 100 is considered 100%).
+	 * If not provided infinite progress is assumed and clients are allowed
+	 * to ignore the `percentage` value in subsequent in report notifications.
+	 * <p>
+	 * The value should be steadily rising. Clients are free to ignore values
+	 * that are not following this rule.
+	 */
+	Integer percentage
+}
+
+/**
+ * The notification payload about progress reporting.
+ * <p>
+ * Since 3.15.0
+ */
+@JsonRpcData
+class WorkDoneProgressReport implements WorkDoneProgressNotification {
+
+	/**
+	 * Always return report
+	 */
+	override WorkDoneProgressKind getKind() {
+		WorkDoneProgressKind.report
+	}
+
+	/**
+	 * Controls enablement state of a cancel button. This property is only valid if a cancel
+	 * button got requested in the {@link WorkDoneProgressBegin} payload.
+	 * <p>
+	 * Clients that don't support cancellation or don't support control the button's
+	 * enablement state are allowed to ignore the setting.
+	 */
+	Boolean cancellable
+
+	/**
+	 * Optional, more detailed associated progress message. Contains
+	 * complementary information to the {@link WorkDoneProgressBegin#title}.
+	 * <p>
+	 * Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
+	 * If unset, the previous progress message (if any) is still valid.
+	 */
+	String message
+
+	/**
+	 * Optional progress percentage to display (value 100 is considered 100%).
+	 * If not provided infinite progress is assumed and clients are allowed
+	 * to ignore the `percentage` value in subsequent in report notifications.
+	 * <p>
+	 * The value should be steadily rising. Clients are free to ignore values
+	 * that are not following this rule.
+	 */
+	Integer percentage
+}
+
+/**
+ * The notification payload about progress reporting.
+ * Signaling the end of a progress reporting is done using the following payload:
+ * <p>
+ * Since 3.15.0
+ */
+@JsonRpcData
+class WorkDoneProgressEnd implements WorkDoneProgressNotification {
+
+	/**
+	 * Always return end
+	 */
+	override WorkDoneProgressKind getKind() {
+		WorkDoneProgressKind.end
+	}
+
+	/**
+	 * Optional, a final message indicating to for example indicate the outcome
+	 * of the operation.
+	 */
+	String message
+}
+
+/**
+ * The base protocol offers also support to report progress in a generic fashion.
+ * This mechanism can be used to report any kind of progress including work done progress
+ * (usually used to report progress in the user interface using a progress bar)
+ * and partial result progress to support streaming of results.
+ * A progress notification has the following properties:
+ * <p>
+ * Since 3.15.0
+ */
+@JsonRpcData
+class ProgressParams {
+	/**
+	 * The progress token provided by the client or server.
+	 */
+	@NonNull
+	Either<String, Integer> token
+
+	/**
+	 * The progress data.
+	 */
+	@NonNull
+	@JsonAdapter(ProgressNotificationAdapter)
+	Either<WorkDoneProgressNotification, Object> value
+
+	new() {
+	}
+
+	new(@NonNull Either<String, Integer> token, @NonNull Either<WorkDoneProgressNotification, Object> value) {
+		this.token = Preconditions.checkNotNull(token, 'token')
+		this.value = Preconditions.checkNotNull(value, 'value')
+	}
+}
+
+
+/**
+ * A parameter literal used to pass a work done progress token.
+ * <p>
+ * Since 3.15.0
+ */
+interface WorkDoneProgressParams {
+	/**
+	 * An optional token that a server can use to report work done progress.
+	 */
+	def Either<String, Integer> getWorkDoneToken()
+
+	/**
+	 * An optional token that a server can use to report work done progress.
+	 */
+	def void setWorkDoneToken(Either<String, Integer> token)
+}
+
+/**
+ * Options to signal work done progress support in server capabilities.
+ * <p>
+ * Since 3.15.0
+ */
+interface WorkDoneProgressOptions {
+
+	def Boolean getWorkDoneProgress()
+
+	def void setWorkDoneProgress(Boolean workDoneProgress)
+
+}
+
+/**
+ * Options to signal work done progress support in server capabilities.
+ * It is not present in protocol specification, so it's just "dry" class.
+ * <p>
+ * Since 3.15.0
+ */
+@JsonRpcData
+abstract class AbstractWorkDoneProgressOptions implements WorkDoneProgressOptions {
+	Boolean workDoneProgress
+}
+
+/**
+ * Options to signal work done progress support in server capabilities and TextDocumentRegistrationOptions.
+ * It is not present in protocol specification, so it's just "dry" class.
+ * <p>
+ * Since 3.15.0
+ */
+@JsonRpcData
+abstract class AbstractTextDocumentRegistrationAndWorkDoneProgressOptions extends TextDocumentRegistrationOptions implements WorkDoneProgressOptions {
+	Boolean workDoneProgress
+
+	new() {
+	}
+
+	new(List<DocumentFilter> documentSelector) {
+		super(documentSelector)
+	}
+}
+
+/**
+ * A parameter literal used to pass a partial result token.
+ * <p>
+ * Since 3.15.0
+ */
+interface PartialResultParams {
+	/**
+	 * An optional token that a server can use to report partial results (e.g. streaming) to
+	 * the client.
+	 */
+	def Either<String, Integer> getPartialResultToken()
+
+	/**
+	 * An optional token that a server can use to report partial results (e.g. streaming) to
+	 * the client.
+	 */
+	def void setPartialResultToken(Either<String, Integer> token)
+}
+
+/**
+ * Abstract class which implements work done progress and partial result request parameter.
+ * It is not present in protocol specification, so it's just "dry" class.
+ * <p>
+ * Since 3.15.0
+ */
+@JsonRpcData
+abstract class WorkDoneProgressAndPartialResultParams implements WorkDoneProgressParams, PartialResultParams {
+	/**
+	 * An optional token that a server can use to report work done progress.
+	 */
+	Either<String, Integer> workDoneToken
+
+	/**
+	 * An optional token that a server can use to report partial results (e.g. streaming) to
+	 * the client.
+	 */
+	Either<String, Integer> partialResultToken
+}
+
+/**
+ * Abstract class which extends TextDocumentPosition and implements work done progress request parameter.
+ * It is not present in protocol specification, so it's just "dry" class.
+ * <p>
+ * Since 3.15.0
+ */
+@JsonRpcData
+abstract class TextDocumentPositionAndWorkDoneProgressParams extends TextDocumentPositionParams implements WorkDoneProgressParams {
+	/**
+	 * An optional token that a server can use to report work done progress.
+	 */
+	Either<String, Integer> workDoneToken
+
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument, @NonNull Position position) {
+		super(textDocument, position)
+	}
+}
+
+/**
+ * Abstract class which extends TextDocumentPosition and implements work done progress and partial result request parameter.
+ * It is not present in protocol specification, so it's just "dry" class.
+ * <p>
+ * Since 3.15.0
+ */
+@JsonRpcData
+abstract class TextDocumentPositionAndWorkDoneProgressAndPartialResultParams extends TextDocumentPositionAndWorkDoneProgressParams implements PartialResultParams {
+	/**
+	 * An optional token that a server can use to report partial results (e.g. streaming) to
+	 * the client.
+	 */
+	Either<String, Integer> partialResultToken
+
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument, @NonNull Position position) {
+		super(textDocument, position)
+	}
+}
+
+@JsonRpcData
+class InitializeError {
+	/**
+	 * Indicates whether the client executes the following retry logic:
+	 * <ol>
+	 * <li>Show the message provided by the ResponseError to the user.
+	 * <li>User selects retry or cancel.
+	 * <li>If user selected retry the initialize method is sent again.
+	 * </ol>
+	 */
+	boolean retry
+
+	new() {
+	}
+
+	new(boolean retry) {
+		this.retry = retry
+	}
+}
+
+/**
+ * Known error codes for an {@link InitializeError}
+ */
+interface InitializeErrorCode {
+	/**
+	 * If the protocol version provided by the client can't be handled by the server.
+	 *
+	 * @deprecated This initialize error got replaced by client capabilities.
+	 * There is no version handshake in version 3.0x
+	 */
+	@Deprecated
+	val unknownProtocolVersion = 1
+}
+
+/**
+ * The initialize request is sent as the first request from the client to the server.
+ */
+@JsonRpcData
+@JsonAdapter(InitializeParamsTypeAdapter.Factory)
+class InitializeParams implements WorkDoneProgressParams {
+	/**
+	 * An optional token that a server can use to report work done progress.
+	 */
+	Either<String, Integer> workDoneToken
+
+	/**
+	 * The process Id of the parent process that started the server.
+	 */
+	Integer processId
+
+	/**
+	 * The rootPath of the workspace. Is null if no folder is open.
+	 *
+	 * @deprecated Use {@link #workspaceFolders} instead.
+	 */
+	@Deprecated
+	String rootPath
+
+	/**
+	 * The rootUri of the workspace. Is null if no folder is open.
+	 * If both {@link #rootPath} and `rootUri` are set, `rootUri` wins.
+	 *
+	 * @deprecated Use {@link #workspaceFolders} instead.
+	 */
+	@Deprecated
+	String rootUri
+
+	/**
+	 * User provided initialization options.
+	 */
+	@JsonAdapter(JsonElementTypeAdapter.Factory)
+	Object initializationOptions
+
+	/**
+	 * The capabilities provided by the client (editor)
+	 */
+	ClientCapabilities capabilities
+
+	/**
+	 * An optional extension to the protocol.
+	 * To tell the server what client (editor) is talking to it.
+	 *
+	 * @deprecated Use {@link #clientInfo} instead.
+	 */
+	@Deprecated
+	String clientName
+
+	/**
+	 * Information about the client
+	 * <p>
+	 * Since 3.15.0
+	 */
+	ClientInfo clientInfo
+
+	/**
+	 * The locale the client is currently showing the user interface
+	 * in. This must not necessarily be the locale of the operating
+	 * system.
+	 * <p>
+	 * Uses IETF language tags as the value's syntax
+	 * (See https://en.wikipedia.org/wiki/IETF_language_tag)
+	 * <p>
+	 * Since 3.16.0
+	 */
+	String locale
+
+	/**
+	 * The initial trace setting.
+	 * For values, see {@link TraceValue}. If omitted trace is disabled ({@link TraceValue#Off}).
+	 */
+	String trace
+
+	/**
+	 * The workspace folders configured in the client when the server starts.
+	 * This property is only available if the client supports workspace folders.
+	 * It can be `null` if the client supports workspace folders but none are
+	 * configured.
+	 * <p>
+	 * Since 3.6.0
+	 */
+	List<WorkspaceFolder> workspaceFolders
+}
+
+@JsonRpcData
+class InitializeResult {
+	/**
+	 * The capabilities the language server provides.
+	 */
+	@NonNull
+	ServerCapabilities capabilities
+
+	/**
+	 * Information about the server.
+	 * <p>
+	 * Since 3.15.0
+	 */
+	ServerInfo serverInfo
+
+	new() {
+	}
+
+	new(@NonNull ServerCapabilities capabilities) {
+		this.capabilities = Preconditions.checkNotNull(capabilities, 'capabilities')
+	}
+
+	new(@NonNull ServerCapabilities capabilities, ServerInfo serverInfo) {
+		this(capabilities)
+		this.serverInfo = serverInfo
+	}
+}
+
+@JsonRpcData
+class InitializedParams {
+}
+
+/**
+ * Information about the client
+ * <p>
+ * Since 3.15.0
+ */
+@JsonRpcData
+class ClientInfo {
+	/**
+	 * The name of the client as defined by the client.
+	 */
+	@NonNull
+	String name
+
+	/**
+	 * The client's version as defined by the client.
+	 */
+	String version
+
+	new() {
+	}
+
+	new(@NonNull String name) {
+		this.name = Preconditions.checkNotNull(name, 'name')
+	}
+
+	new(@NonNull String name, String version) {
+		this(name)
+		this.version = version
+	}
+}
+
+/**
+ * Information about the server.
+ * <p>
+ * Since 3.15.0
+ */
+@JsonRpcData
+class ServerInfo {
+	/**
+	 * The name of the server as defined by the server.
+	 */
+	@NonNull
+	String name
+
+	/**
+	 * The server's version as defined by the server.
+	 */
+	String version
+
+	new() {
+	}
+
+	new(@NonNull String name) {
+		this.name = Preconditions.checkNotNull(name, 'name')
+	}
+
+	new(@NonNull String name, String version) {
+		this(name)
+		this.version = version
+	}
+}
+
+/**
+ * Represents a location inside a resource, such as a line inside a text file.
+ */
+@JsonRpcData
+class Location {
+	@NonNull
+	String uri
+
+	@NonNull
+	Range range
+
+	new() {
+	}
+
+	new(@NonNull String uri, @NonNull Range range) {
+		this.uri = Preconditions.checkNotNull(uri, 'uri')
+		this.range = Preconditions.checkNotNull(range, 'range')
+	}
+}
+
+/**
+ * Represents a link between a source and a target location.
+ */
+@JsonRpcData
+class LocationLink {
+	/**
+	 * Span of the origin of this link.
+	 * <p>
+	 * Used as the underlined span for mouse interaction. Defaults to the word range at
+	 * the mouse position.
+	 */
+	Range originSelectionRange
+
+	/**
+	 * The target resource identifier of this link.
+	 */
+	@NonNull
+	String targetUri
+
+	/**
+	 * The full target range of this link. If the target for example is a symbol then target range is the
+	 * range enclosing this symbol not including leading/trailing whitespace but everything else
+	 * like comments. This information is typically used to highlight the range in the editor.
+	 */
+	@NonNull
+	Range targetRange
+
+	/**
+	 * The range that should be selected and revealed when this link is being followed, e.g the name of a function.
+	 * Must be contained by the the {@link #targetRange}. See also {@link DocumentSymbol#range}
+	 */
+	@NonNull
+	Range targetSelectionRange
+
+	new() {
+	}
+
+	new(@NonNull String targetUri, @NonNull Range targetRange, @NonNull Range targetSelectionRange) {
+		this.targetUri = Preconditions.checkNotNull(targetUri, 'targetUri')
+		this.targetRange = Preconditions.checkNotNull(targetRange, 'targetRange')
+		this.targetSelectionRange = Preconditions.checkNotNull(targetSelectionRange, 'targetSelectionRange')
+	}
+
+	new(@NonNull String targetUri, @NonNull Range targetRange, @NonNull Range targetSelectionRange, Range originSelectionRange) {
+		this(targetUri, targetRange, targetSelectionRange)
+		this.originSelectionRange = originSelectionRange
+	}
+}
+
+/**
+ * The show message request is sent from a server to a client to ask the client to display a particular message in the
+ * user class. In addition to the show message notification the request allows to pass actions and to wait for an
+ * answer from the client.
+ */
+@JsonRpcData
+class MessageActionItem {
+	/**
+	 * A short title like 'Retry', 'Open Log' etc.
+	 */
+	@NonNull
+	String title
+
+	new() {
+	}
+
+	new(@NonNull String title) {
+		this.title = Preconditions.checkNotNull(title, 'title')
+	}
+}
+
+/**
+ * The show message notification is sent from a server to a client to ask the client to display a particular message
+ * in the user class.
+ * <p>
+ * The log message notification is send from the server to the client to ask the client to log a particular message.
+ */
+@JsonRpcData
+class MessageParams {
+	/**
+	 * The message type.
+	 */
+	@NonNull
+	MessageType type
+
+	/**
+	 * The actual message.
+	 */
+	@NonNull
+	String message
+
+	new() {
+	}
+
+	new(@NonNull MessageType type, @NonNull String message) {
+		this.type = Preconditions.checkNotNull(type, 'type')
+		this.message = Preconditions.checkNotNull(message, 'message')
+	}
+}
+
+/**
+ * A notification to log the trace of the server's execution. The amount and content of these notifications
+ * depends on the current trace configuration. If trace is 'off', the server should not send any logTrace
+ * notification. If trace is 'message', the server should not add the 'verbose' field.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class LogTraceParams {
+	/**
+	 * The message to be logged.
+	 */
+	@NonNull
+	String message
+
+	/**
+	 * Additional information that can be computed if the {@code trace} configuration
+	 * is set to {@link TraceValue#Verbose}
+	 */
+	String verbose
+
+	new() {
+	}
+
+	new(@NonNull String message) {
+		this.message = Preconditions.checkNotNull(message, 'message')
+	}
+
+	new(@NonNull String message, String verbose) {
+		this.message = Preconditions.checkNotNull(message, 'message')
+		this.verbose = verbose
+	}
+}
+
+/**
+ * A notification that should be used by the client to modify the trace setting of the server.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class SetTraceParams {
+	/**
+	 * The new value that should be assigned to the trace setting.
+	 * For values, see {@link TraceValue}.
+	 */
+	@NonNull
+	String value
+
+	new() {
+	}
+
+	new(@NonNull String value) {
+		this.value = Preconditions.checkNotNull(value, 'value')
+	}
+}
+
+/**
+ * Represents a parameter of a callable-signature. A parameter can have a label and a doc-comment.
+ */
+@JsonRpcData
+class ParameterInformation {
+	/**
+	 * The label of this parameter information.
+	 * <p>
+	 * Either a string or an inclusive start and exclusive end offsets within its containing
+	 * signature label (see {@link SignatureInformation#label}). The offsets are based on a UTF-16
+	 * string representation as {@link Position} and {@link Range} does.
+	 * <p>
+	 * <em>Note</em>: a label of type string should be a substring of its containing signature label.
+	 * Its intended use case is to highlight the parameter label part in the {@link SignatureInformation#label}.
+	 */
+	@NonNull
+	Either<String, Tuple.Two<Integer, Integer>> label
+
+	/**
+	 * The human-readable doc-comment of this signature. Will be shown in the UI but can be omitted.
+	 */
+	Either<String, MarkupContent> documentation
+
+	new() {
+	}
+
+	new(@NonNull String label) {
+		this.label = Preconditions.checkNotNull(label, 'label')
+	}
+
+	new(@NonNull String label, String documentation) {
+		this(label)
+		this.documentation = documentation
+	}
+
+	new(@NonNull String label, MarkupContent documentation) {
+		this(label)
+		this.documentation = documentation
+	}
+}
+
+/**
+ * Position in a text document expressed as zero-based line and character offset.
+ */
+@JsonRpcData
+class Position {
+	/**
+	 * Line position in a document (zero-based).
+	 */
+	int line
+
+	/**
+	 * Character offset on a line in a document (zero-based).
+	 */
+	int character
+
+	new() {
+	}
+
+	new(int line, int character) {
+		this.line = line
+		this.character = character
+	}
+}
+
+/**
+ * Diagnostics notification are sent from the server to the client to signal results of validation runs.
+ */
+@JsonRpcData
+class PublishDiagnosticsParams {
+	/**
+	 * The URI for which diagnostic information is reported.
+	 */
+	@NonNull
+	String uri
+
+	/**
+	 * An array of diagnostic information items.
+	 */
+	@NonNull
+	List<Diagnostic> diagnostics
+
+	/**
+	 * Optional the version number of the document the diagnostics are published for.
+	 * <p>
+	 * Since 3.15.0
+	 */
+	Integer version
+
+	new() {
+		this.diagnostics = new ArrayList
+	}
+
+	new(@NonNull String uri, @NonNull List<Diagnostic> diagnostics) {
+		this.uri = Preconditions.checkNotNull(uri, 'uri')
+		this.diagnostics = Preconditions.checkNotNull(diagnostics, 'diagnostics')
+	}
+
+	new(@NonNull String uri, @NonNull List<Diagnostic> diagnostics, Integer version) {
+		this(uri, diagnostics)
+		this.version = version
+	}
+}
+
+/**
+ * A range in a text document expressed as (zero-based) start and end positions.
+ */
+@JsonRpcData
+class Range {
+	/**
+	 * The range's start position
+	 */
+	@NonNull
+	Position start
+
+	/**
+	 * The range's end position
+	 */
+	@NonNull
+	Position end
+
+	new() {
+	}
+
+	new(@NonNull Position start, @NonNull Position end) {
+		this.start = Preconditions.checkNotNull(start, 'start')
+		this.end = Preconditions.checkNotNull(end, 'end')
+	}
+}
+
+/**
+ * The references request is sent from the client to the server to resolve project-wide references for the symbol
+ * denoted by the given text document position.
+ */
+@JsonRpcData
+class ReferenceContext {
+	/**
+	 * Include the declaration of the current symbol.
+	 */
+	boolean includeDeclaration
+
+	new() {
+	}
+
+	new(boolean includeDeclaration) {
+		this.includeDeclaration = includeDeclaration
+	}
+}
+
+@JsonRpcData
+class ReferenceOptions extends AbstractWorkDoneProgressOptions {
+}
+
+@JsonRpcData
+class ReferenceRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+}
+
+/**
+ * The references request is sent from the client to the server to resolve project-wide references for the symbol
+ * denoted by the given text document position.
+ */
+@JsonRpcData
+class ReferenceParams extends TextDocumentPositionAndWorkDoneProgressAndPartialResultParams {
+	@NonNull
+	ReferenceContext context
+
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument, @NonNull Position position, @NonNull ReferenceContext context) {
+		super(textDocument, position)
+		this.context = Preconditions.checkNotNull(context, 'context')
+	}
+
+	@Deprecated
+	new(@NonNull ReferenceContext context) {
+		this.context = Preconditions.checkNotNull(context, 'context')
+	}
+}
+
+/**
+ * One of the result types of the `textDocument/prepareRename` request.
+ * Provides the range of the string to rename and a placeholder text of the string content to be renamed.
+ */
+@JsonRpcData
+class PrepareRenameResult {
+	/**
+	 * The range of the string to rename
+	 */
+	@NonNull
+	Range range
+
+	/*
+	 * A placeholder text of the string content to be renamed.
+	 */
+	@NonNull
+	String placeholder
+
+	new() {
+	}
+
+	new(@NonNull Range range, @NonNull String placeholder) {
+		this.range = Preconditions.checkNotNull(range, 'range')
+		this.placeholder = Preconditions.checkNotNull(placeholder, 'placeholder')
+	}
+}
+
+/**
+ * The rename request is sent from the client to the server to do a workspace wide rename of a symbol.
+ */
+@JsonRpcData
+class RenameParams extends TextDocumentPositionAndWorkDoneProgressParams {
+	/**
+	 * The new name of the symbol. If the given name is not valid the request must return a
+	 * ResponseError with an appropriate message set.
+	 */
+	@NonNull
+	String newName
+
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument, @NonNull Position position, @NonNull String newName) {
+		super(textDocument, position)
+		this.newName = Preconditions.checkNotNull(newName, 'newName')
+	}
+}
+
+/**
+ * The linked editing range request is sent from the client to the server to return for a given position
+ * in a document the range of the symbol at the position and all ranges that have the same content.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class LinkedEditingRangeParams extends TextDocumentPositionAndWorkDoneProgressParams {
+}
+
+/**
+ * Linked editing range options.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class LinkedEditingRangeOptions extends AbstractWorkDoneProgressOptions {
+}
+
+/**
+ * Linked editing range registration options.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class LinkedEditingRangeRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+	/**
+	 * The id used to register the request. The id can be used to deregister
+	 * the request again. See also Registration#id.
+	 */
+	String id
+
+	new() {
+	}
+
+	new(String id) {
+		this.id = id
+	}
+}
+
+/**
+ * The linked editing range response is sent from the server to the client to return the range of the symbol
+ * at the given position and all ranges that have the same content.
+ * <p>
+ * Optionally a word pattern can be returned to describe valid contents.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class LinkedEditingRanges {
+	/**
+	 * A list of ranges that can be renamed together. The ranges must have
+	 * identical length and contain identical text content. The ranges cannot overlap.
+	 */
+	@NonNull
+	List<Range> ranges
+
+	/**
+	 * An optional word pattern (regular expression) that describes valid contents for
+	 * the given ranges. If no pattern is provided, the client configuration's word
+	 * pattern will be used.
+	 */
+	String wordPattern
+
+	new() {
+		this.ranges = new ArrayList
+	}
+
+	new(@NonNull List<Range> ranges) {
+		this.ranges = Preconditions.checkNotNull(ranges, 'ranges')
+	}
+
+	new(@NonNull List<Range> ranges, String wordPattern) {
+		this(ranges)
+		this.wordPattern = wordPattern
+	}
+}
+
+/**
+ * The legend used by the server
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class SemanticTokensLegend {
+
+	/**
+	 * The token types that the client supports.
+	 */
+	@NonNull
+	List<String> tokenTypes
+
+	/**
+	 * The token modifiers that the client supports.
+	 */
+	@NonNull
+	List<String> tokenModifiers
+
+	new(@NonNull List<String> tokenTypes, @NonNull List<String> tokenModifiers) {
+		this.tokenTypes = Preconditions.checkNotNull(tokenTypes, 'tokenTypes')
+		this.tokenModifiers = Preconditions.checkNotNull(tokenModifiers, 'tokenModifiers')
+	}
+
+}
+
+/**
+ * Server supports providing semantic tokens for a full document.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class SemanticTokensServerFull {
+
+	/**
+	* The server supports deltas for full documents.
+	*/
+	Boolean delta
+
+	new() {
+	}
+
+	new(Boolean delta) {
+		this.delta = delta
+	}
+}
+
+/**
+ * Since 3.16.0
+ */
+@JsonRpcData
+class SemanticTokensWithRegistrationOptions extends AbstractWorkDoneProgressOptions {
+
+	/**
+	 * The legend used by the server
+	 */
+	@NonNull
+	SemanticTokensLegend legend
+
+	/**
+	 * Server supports providing semantic tokens for a specific range
+	 * of a document.
+	 */
+	Either<Boolean, Object> range
+
+	/**
+	 * Server supports providing semantic tokens for a full document.
+	 */
+	Either<Boolean, SemanticTokensServerFull> full
+
+	/**
+	 * A document selector to identify the scope of the registration. If set to null
+	 * the document selector provided on the client side will be used.
+	 */
+	List<DocumentFilter> documentSelector
+
+	/**
+	 * The id used to register the request. The id can be used to deregister
+	 * the request again. See also Registration#id.
+	 */
+	String id
+
+	new() {
+	}
+
+	new(@NonNull SemanticTokensLegend legend) {
+		this.legend = Preconditions.checkNotNull(legend, 'legend')
+	}
+
+	new(@NonNull SemanticTokensLegend legend, Boolean full) {
+		this(legend)
+		this.full = full
+	}
+
+	new(@NonNull SemanticTokensLegend legend, SemanticTokensServerFull full) {
+		this(legend)
+		this.full = full
+	}
+
+	new(@NonNull SemanticTokensLegend legend, Boolean full, Boolean range) {
+		this(legend)
+		this.full = full
+		this.range = range
+	}
+
+	new(@NonNull SemanticTokensLegend legend, SemanticTokensServerFull full, Boolean range) {
+		this(legend)
+		this.full = full
+		this.range = range
+	}
+
+	new(@NonNull SemanticTokensLegend legend, SemanticTokensServerFull full, Boolean range, List<DocumentFilter> documentSelector) {
+		this(legend)
+		this.full = full
+		this.range = range
+		this.documentSelector = documentSelector
+	}
+
+}
+
+/**
+ * The server can signal these capabilities
+ */
+@JsonRpcData
+class ServerCapabilities {
+	/**
+	 * Defines how text documents are synced. Is either a detailed structure defining each notification or
+	 * for backwards compatibility the TextDocumentSyncKind number. If omitted it defaults to
+	 * {@link TextDocumentSyncKind#None}
+	 */
+	Either<TextDocumentSyncKind, TextDocumentSyncOptions> textDocumentSync
+
+	/**
+	 * The server provides hover support.
+	 */
+	Either<Boolean, HoverOptions> hoverProvider
+
+	/**
+	 * The server provides completion support.
+	 */
+	CompletionOptions completionProvider
+
+	/**
+	 * The server provides signature help support.
+	 */
+	SignatureHelpOptions signatureHelpProvider
+
+	/**
+	 * The server provides goto definition support.
+	 */
+	Either<Boolean, DefinitionOptions> definitionProvider
+
+	/**
+	 * The server provides Goto Type Definition support.
+	 * <p>
+	 * Since 3.6.0
+	 */
+	Either<Boolean, TypeDefinitionRegistrationOptions> typeDefinitionProvider
+
+	/**
+	 * The server provides Goto Implementation support.
+	 * <p>
+	 * Since 3.6.0
+	 */
+	Either<Boolean, ImplementationRegistrationOptions> implementationProvider
+
+	/**
+	 * The server provides find references support.
+	 */
+	Either<Boolean, ReferenceOptions> referencesProvider
+
+	/**
+	 * The server provides document highlight support.
+	 */
+	Either<Boolean, DocumentHighlightOptions> documentHighlightProvider
+
+	/**
+	 * The server provides document symbol support.
+	 */
+	Either<Boolean, DocumentSymbolOptions> documentSymbolProvider
+
+	/**
+	 * The server provides workspace symbol support.
+	 */
+	Either<Boolean, WorkspaceSymbolOptions> workspaceSymbolProvider
+
+	/**
+	 * The server provides code actions. The {@link CodeActionOptions} return type is only
+	 * valid if the client signals code action literal support via the property
+	 * {@link CodeActionCapabilities#codeActionLiteralSupport}.
+	 */
+	Either<Boolean, CodeActionOptions> codeActionProvider
+
+	/**
+	 * The server provides code lens.
+	 */
+	CodeLensOptions codeLensProvider
+
+	/**
+	 * The server provides document formatting.
+	 */
+	Either<Boolean, DocumentFormattingOptions> documentFormattingProvider
+
+	/**
+	 * The server provides document range formatting.
+	 */
+	Either<Boolean, DocumentRangeFormattingOptions> documentRangeFormattingProvider
+
+	/**
+	 * The server provides document formatting on typing.
+	 */
+	DocumentOnTypeFormattingOptions documentOnTypeFormattingProvider
+
+	/**
+	 * The server provides rename support.
+	 */
+	Either<Boolean, RenameOptions> renameProvider
+
+	/**
+	 * The server provides document link support.
+	 */
+	DocumentLinkOptions documentLinkProvider
+
+	/**
+	 * The server provides color provider support.
+	 * <p>
+	 * Since 3.6.0
+	 */
+	Either<Boolean, ColorProviderOptions> colorProvider
+
+	/**
+	 * The server provides folding provider support.
+	 * <p>
+	 * Since 3.10.0
+	 */
+	Either<Boolean, FoldingRangeProviderOptions> foldingRangeProvider
+
+	/**
+	 * The server provides go to declaration support.
+	 * <p>
+	 * Since 3.14.0
+	 */
+	Either<Boolean, DeclarationRegistrationOptions> declarationProvider
+
+	/**
+	 * The server provides execute command support.
+	 */
+	ExecuteCommandOptions executeCommandProvider
+
+	/**
+	 * Workspace specific server capabilities
+	 */
+	WorkspaceServerCapabilities workspace
+
+	/**
+	 * Server capability for calculating super- and subtype hierarchies.
+	 * The LS supports the type hierarchy language feature, if this capability is set to {@code true}.
+	 * <p>
+	 * <b>Note:</b> the <a href=
+	 * "https://github.com/Microsoft/vscode-languageserver-node/pull/426">{@code textDocument/typeHierarchy}
+	 * language feature</a> is not yet part of the official LSP specification.
+	 */
+	@Beta
+	Either<Boolean, StaticRegistrationOptions> typeHierarchyProvider
+
+	/**
+	 * The server provides Call Hierarchy support.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	Either<Boolean, CallHierarchyRegistrationOptions> callHierarchyProvider
+
+	/**
+	 * The server provides selection range support.
+	 * <p>
+	 * Since 3.15.0
+	 */
+	Either<Boolean, SelectionRangeRegistrationOptions> selectionRangeProvider
+
+	/**
+	 * The server provides linked editing range support.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	Either<Boolean, LinkedEditingRangeRegistrationOptions> linkedEditingRangeProvider
+
+	/**
+	 * The server provides semantic tokens support.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	SemanticTokensWithRegistrationOptions semanticTokensProvider
+
+	/**
+	 * Whether server provides moniker support.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	Either<Boolean, MonikerRegistrationOptions> monikerProvider
+
+	/**
+	 * Experimental server capabilities.
+	 */
+	@JsonAdapter(JsonElementTypeAdapter.Factory)
+	Object experimental
+
+}
+
+/**
+ * Workspace specific server capabilities
+ */
+@JsonRpcData
+class WorkspaceServerCapabilities {
+	/**
+	 * The server supports workspace folder.
+	 * <p>
+	 * Since 3.6.0
+	 */
+	WorkspaceFoldersOptions workspaceFolders
+
+	/**
+	 * The server is interested in file notifications/requests.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	FileOperationsServerCapabilities fileOperations
+
+	new() {
+	}
+
+	new(WorkspaceFoldersOptions workspaceFolders) {
+		this.workspaceFolders = workspaceFolders
+	}
+}
+
+/**
+ * The show message request is sent from a server to a client to ask the client to display a particular message in the
+ * user class. In addition to the show message notification the request allows to pass actions and to wait for an
+ * answer from the client.
+ */
+@JsonRpcData
+class ShowMessageRequestParams extends MessageParams {
+	/**
+	 * The message action items to present.
+	 */
+	List<MessageActionItem> actions
+
+	new() {
+	}
+
+	new(List<MessageActionItem> actions) {
+		this.actions = actions
+	}
+}
+
+/**
+ * The signature help request is sent from the client to the server to request signature information at a given cursor position.
+ */
+@JsonRpcData
+class SignatureHelpParams extends TextDocumentPositionAndWorkDoneProgressParams {
+	/**
+	 * The signature help context. This is only available if the client specifies
+	 * to send this using the client capability {@link SignatureHelpCapabilities#contextSupport} as true.
+	 * <p>
+	 * Since 3.15.0
+	 */
+	SignatureHelpContext context
+
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument, @NonNull Position position) {
+		super(textDocument, position)
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument, @NonNull Position position, SignatureHelpContext context) {
+		this(textDocument, position)
+		this.context = context
+	}
+}
+
+/**
+ * The request is sent from the client to the server to resolve semantic tokens for a given whole file.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class SemanticTokensParams extends WorkDoneProgressAndPartialResultParams {
+	/**
+	 * The text document.
+	 */
+	@NonNull
+	TextDocumentIdentifier textDocument
+
+	new(@NonNull TextDocumentIdentifier textDocument) {
+		this.textDocument = Preconditions.checkNotNull(textDocument, 'textDocument')
+	}
+}
+
+/**
+ * Since 3.16.0
+ */
+@JsonRpcData
+class SemanticTokens {
+
+	/**
+	 * An optional result id. If provided and clients support delta updating
+	 * the client will include the result id in the next semantic token request.
+	 * A server can then instead of computing all semantic tokens again simply
+	 * send a delta.
+	 */
+	String resultId
+
+	/**
+	 * The actual tokens.
+	 */
+	@NonNull
+	List<Integer> data
+
+	new(@NonNull List<Integer> data) {
+		this.data = Preconditions.checkNotNull(data, 'data')
+	}
+
+	new(String resultId, @NonNull List<Integer> data) {
+		this(data)
+		this.resultId = resultId
+	}
+}
+
+/**
+ * Since 3.16.0
+ */
+@JsonRpcData
+class SemanticTokensPartialResult {
+
+	@NonNull
+	List<Integer> data
+
+	new(@NonNull List<Integer> data) {
+		this.data = Preconditions.checkNotNull(data, 'data')
+	}
+}
+
+/**
+ * The request is sent from the client to the server to resolve semantic token deltas for a given whole file.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class SemanticTokensDeltaParams extends WorkDoneProgressAndPartialResultParams {
+	/**
+	 * The text document.
+	 */
+	@NonNull
+	TextDocumentIdentifier textDocument
+
+	/**
+	 * The result id of a previous response. The result Id can either point to a full response
+	 * or a delta response depending on what was received last.
+	 */
+	@NonNull
+	String previousResultId
+
+	new(@NonNull TextDocumentIdentifier textDocument, @NonNull String previousResultId) {
+		this.textDocument = Preconditions.checkNotNull(textDocument, 'textDocument')
+		this.previousResultId = Preconditions.checkNotNull(previousResultId, 'previousResultId')
+	}
+}
+
+/**
+ * Since 3.16.0
+ */
+@JsonRpcData
+class SemanticTokensEdit {
+
+	/**
+	 * The start offset of the edit.
+	 */
+	int start
+
+	/**
+	 * The count of elements to remove.
+	 */
+	int deleteCount
+
+	/**
+	 * The elements to insert.
+	 */
+	List<Integer> data
+
+	new(int start, int deleteCount, List<Integer> data) {
+		this.start = start
+		this.deleteCount = deleteCount
+		this.data = data
+	}
+}
+
+/**
+ * Since 3.16.0
+ */
+@JsonRpcData
+class SemanticTokensDelta {
+
+	String resultId
+
+	/**
+	 * The semantic token edits to transform a previous result into a new result.
+	 */
+	@NonNull
+	List<SemanticTokensEdit> edits
+
+	new(@NonNull List<SemanticTokensEdit> edits) {
+		this.edits = Preconditions.checkNotNull(edits, 'edits')
+	}
+
+	new(@NonNull List<SemanticTokensEdit> edits, String resultId) {
+		this.edits = Preconditions.checkNotNull(edits, 'edits')
+		this.resultId = resultId
+	}
+}
+
+/**
+ * Since 3.16.0
+ */
+@JsonRpcData
+class SemanticTokensDeltaPartialResult {
+
+	@NonNull
+	List<SemanticTokensEdit> edits
+
+	new(@NonNull List<SemanticTokensEdit> edits) {
+		this.edits = Preconditions.checkNotNull(edits, 'edits')
+	}
+}
+
+/**
+ * The request is sent from the client to the server to resolve semantic tokens for a range in a given file.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class SemanticTokensRangeParams extends WorkDoneProgressAndPartialResultParams {
+	/**
+	 * The text document.
+	 */
+	@NonNull
+	TextDocumentIdentifier textDocument
+
+	/**
+	 * The range the semantic tokens are requested for.
+	 */
+	@NonNull
+	Range range
+
+	new(@NonNull TextDocumentIdentifier textDocument, @NonNull Range range) {
+		this.textDocument = Preconditions.checkNotNull(textDocument, 'textDocument')
+		this.range = Preconditions.checkNotNull(range, 'range')
+	}
+}
+
+/**
+ * Additional information about the context in which a signature help request was triggered.
+ * <p>
+ * Since 3.15.0
+ */
+@JsonRpcData
+class SignatureHelpContext {
+	/**
+	 * Action that caused signature help to be triggered.
+	 */
+	@NonNull
+	SignatureHelpTriggerKind triggerKind
+
+	/**
+	 * Character that caused signature help to be triggered.
+	 * <p>
+	 * This is undefined when {@link #triggerKind} is not {@link SignatureHelpTriggerKind#TriggerCharacter}
+	 */
+	String triggerCharacter
+
+	/**
+	 * {@code true} if signature help was already showing when it was triggered.
+	 * <p>
+	 * Retriggers occur when the signature help is already active and can be caused by actions such as
+	 * typing a trigger character, a cursor move, or document content changes.
+	 */
+	boolean isRetrigger
+
+	/**
+	 * The currently active {@link SignatureHelp}.
+	 * <p>
+	 * The `activeSignatureHelp` has its {@link SignatureHelp#activeSignature} field updated based on
+	 * the user navigating through available signatures.
+	 */
+	SignatureHelp activeSignatureHelp
+
+	new() {
+	}
+
+	new(@NonNull SignatureHelpTriggerKind triggerKind, boolean isRetrigger) {
+		this.triggerKind = Preconditions.checkNotNull(triggerKind, 'triggerKind')
+		this.isRetrigger = isRetrigger
+	}
+}
+
+/**
+ * Signature help represents the signature of something callable. There can be multiple signature but only one
+ * active and only one active parameter.
+ */
+@JsonRpcData
+class SignatureHelp {
+	/**
+	 * One or more signatures.
+	 */
+	@NonNull
+	List<SignatureInformation> signatures
+
+	/**
+	 * The active signature. If omitted or the value lies outside the
+	 * range of {@link #signatures} the value defaults to zero or is ignored if
+	 * the {@code SignatureHelp} has no signatures. Whenever possible implementors should
+	 * make an active decision about the active signature and shouldn't
+	 * rely on a default value.
+	 * <p>
+	 * In future version of the protocol this property might become
+	 * mandatory to better express this.
+	 */
+	Integer activeSignature
+
+	/**
+	 * The active parameter of the active signature. If omitted or the value
+	 * lies outside the range of {@code signatures[activeSignature].parameters}
+	 * defaults to 0 if the active signature has parameters. If
+	 * the active signature has no parameters it is ignored.
+	 * <p>
+	 * In future version of the protocol this property might become
+	 * mandatory to better express the active parameter if the
+	 * active signature does have any.
+	 */
+	Integer activeParameter
+
+	new() {
+		this.signatures = new ArrayList
+	}
+
+	new(@NonNull List<SignatureInformation> signatures, Integer activeSignature, Integer activeParameter) {
+		this.signatures = Preconditions.checkNotNull(signatures, 'signatures')
+		this.activeSignature = activeSignature
+		this.activeParameter = activeParameter
+	}
+}
+
+/**
+ * Signature help options.
+ */
+@JsonRpcData
+class SignatureHelpOptions extends AbstractWorkDoneProgressOptions {
+
+	/**
+	 * The characters that trigger signature help automatically.
+	 */
+	List<String> triggerCharacters
+
+	/**
+	 * List of characters that re-trigger signature help.
+	 * <p>
+	 * These trigger characters are only active when signature help is already showing. All trigger characters
+	 * are also counted as re-trigger characters.
+	 * <p>
+	 * Since 3.15.0
+	 */
+	List<String> retriggerCharacters
+
+	new() {
+	}
+
+	new(List<String> triggerCharacters) {
+		this.triggerCharacters = triggerCharacters
+	}
+
+	new(List<String> triggerCharacters, List<String> retriggerCharacters) {
+		this(triggerCharacters)
+		this.retriggerCharacters = retriggerCharacters
+	}
+}
+
+/**
+ * Represents the signature of something callable. A signature can have a label, like a function-name, a doc-comment, and
+ * a set of parameters.
+ */
+@JsonRpcData
+class SignatureInformation {
+	/**
+	 * The label of this signature. Will be shown in the UI.
+	 */
+	@NonNull
+	String label
+
+	/**
+	 * The human-readable doc-comment of this signature. Will be shown in the UI but can be omitted.
+	 */
+	Either<String, MarkupContent> documentation
+
+	/**
+	 * The parameters of this signature.
+	 */
+	List<ParameterInformation> parameters
+
+	/**
+	 * The index of the active parameter.
+	 * <p>
+	 * If provided, this is used in place of {@link SignatureHelp#activeParameter}.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	Integer activeParameter
+
+	new() {
+	}
+
+	new(@NonNull String label) {
+		this.label = Preconditions.checkNotNull(label, 'label')
+	}
+
+	new(@NonNull String label, String documentation, List<ParameterInformation> parameters) {
+		this(label)
+		this.documentation = documentation
+		this.parameters = parameters
+	}
+
+	new(@NonNull String label, MarkupContent documentation, List<ParameterInformation> parameters) {
+		this(label)
+		this.documentation = documentation
+		this.parameters = parameters
+	}
+}
+
+/**
+ * Representation of an item that carries type information (such as class, interface, enumeration, etc) with additional parentage details.
+ */
+@Beta
+@JsonRpcData
+class TypeHierarchyItem {
+
+	/**
+	 * The human readable name of the hierarchy item.
+	 */
+	@NonNull
+	String name
+
+	/**
+	 * Optional detail for the hierarchy item. It can be, for instance, the signature of a function or method.
+	 */
+	String detail
+
+	/**
+	 * The kind of the hierarchy item. For instance, class or interface.
+	 */
+	@NonNull
+	SymbolKind kind
+
+	/**
+	 * {@code true} if the hierarchy item is deprecated. Otherwise, {@code false}. It is {@code false} by default.
+	 */
+	Boolean deprecated
+
+	/**
+	 * The URI of the text document where this type hierarchy item belongs to.
+	 */
+	@NonNull
+	String uri
+
+	/**
+	 * The range enclosing this type hierarchy item not including leading/trailing whitespace but everything else
+	 * like comments. This information is typically used to determine if the clients cursor is inside the type
+	 * hierarchy item to reveal in the symbol in the UI.
+	 *
+	 * @see TypeHierarchyItem#selectionRange
+	 */
+	@NonNull
+	Range range
+
+	/**
+	 * The range that should be selected and revealed when this type hierarchy item is being picked, e.g the name of a function.
+	 * Must be contained by the the {@link TypeHierarchyItem#getRange range}.
+	 *
+	 * @see TypeHierarchyItem#range
+	 */
+	@NonNull
+	Range selectionRange
+
+	/**
+	 * If this type hierarchy item is resolved, it contains the direct parents. Could be empty if the item does not have any
+	 * direct parents. If not defined, the parents have not been resolved yet.
+	 */
+	List<TypeHierarchyItem> parents
+
+	/**
+	 * If this type hierarchy item is resolved, it contains the direct children of the current item.
+	 * Could be empty if the item does not have any descendants. If not defined, the children have not been resolved.
+	 */
+	List<TypeHierarchyItem> children
+
+	/**
+	 * An optional data field can be used to identify a type hierarchy item in a resolve request.
+	 */
+	@JsonAdapter(JsonElementTypeAdapter.Factory)
+	Object data
+
+}
+
+/**
+ * Represents programming constructs like variables, classes, interfaces etc. that appear in a document. Document symbols can be
+ * hierarchical and they have two ranges: one that encloses its definition and one that points to its most interesting range,
+ * e.g. the range of an identifier.
+ */
+@JsonRpcData
+class DocumentSymbol {
+
+	/**
+	 * The name of this symbol.
+	 */
+	@NonNull
+	String name
+
+	/**
+	 * The kind of this symbol.
+	 */
+	@NonNull
+	SymbolKind kind
+
+	/**
+	 * The range enclosing this symbol not including leading/trailing whitespace but everything else
+	 * like comments. This information is typically used to determine if the clients cursor is
+	 * inside the symbol to reveal in the symbol in the UI.
+	 */
+	@NonNull
+	Range range
+
+	/**
+	 * The range that should be selected and revealed when this symbol is being picked, e.g the name of a function.
+	 * Must be contained by the {@link #range}.
+	 */
+	@NonNull
+	Range selectionRange
+
+	/**
+	 * More detail for this symbol, e.g the signature of a function. If not provided the
+	 * name is used.
+	 */
+	String detail
+
+	/**
+	 * Tags for this document symbol.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	List<SymbolTag> tags
+
+	/**
+	 * Indicates if this symbol is deprecated.
+	 *
+	 * @deprecated Use {@link #tags} instead if supported.
+	 */
+	@Deprecated
+	Boolean deprecated
+
+	/**
+	 * Children of this symbol, e.g. properties of a class.
+	 */
+	List<DocumentSymbol> children
+
+	new() {
+	}
+
+	new(@NonNull String name, @NonNull SymbolKind kind, @NonNull Range range, @NonNull Range selectionRange) {
+		this.name = Preconditions.checkNotNull(name, 'name')
+		this.kind = Preconditions.checkNotNull(kind, 'kind')
+		this.range = Preconditions.checkNotNull(range, 'range')
+		this.selectionRange = Preconditions.checkNotNull(selectionRange, 'selectionRange')
+	}
+
+	new(@NonNull String name, @NonNull SymbolKind kind, @NonNull Range range, @NonNull Range selectionRange,
+		String detail) {
+		this(name, kind, range, selectionRange)
+		this.detail = detail
+	}
+
+	new(@NonNull String name, @NonNull SymbolKind kind, @NonNull Range range, @NonNull Range selectionRange,
+		String detail, List<DocumentSymbol> children) {
+		this(name, kind, range, selectionRange)
+		this.detail = detail
+		this.children = children
+	}
+}
+
+/**
+ * Represents information about programming constructs like variables, classes, interfaces etc.
+ */
+@JsonRpcData
+@JsonAdapter(SymbolInformationTypeAdapter.Factory)
+class SymbolInformation {
+	/**
+	 * The name of this symbol.
+	 */
+	@NonNull
+	String name
+
+	/**
+	 * The kind of this symbol.
+	 */
+	@NonNull
+	SymbolKind kind
+
+	/**
+	 * Tags for this symbol.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	List<SymbolTag> tags
+
+	/**
+	 * Indicates if this symbol is deprecated.
+	 *
+	 * @deprecated Use {@link #tags} instead if supported.
+	 */
+	@Deprecated
+	Boolean deprecated
+
+	/**
+	 * The location of this symbol. The location's range is used by a tool
+	 * to reveal the location in the editor. If the symbol is selected in the
+	 * tool the range's start information is used to position the cursor. So
+	 * the range usually spans more then the actual symbol's name and does
+	 * normally include things like visibility modifiers.
+	 * <p>
+	 * The range doesn't have to denote a node range in the sense of a abstract
+	 * syntax tree. It can therefore not be used to re-construct a hierarchy of
+	 * the symbols.
+	 */
+	@NonNull
+	Location location
+
+	/**
+	 * The name of the symbol containing this symbol. This information is for
+	 * user interface purposes (e.g. to render a qualifier in the user interface
+	 * if necessary). It can't be used to re-infer a hierarchy for the document
+	 * symbols.
+	 */
+	String containerName
+
+	new() {
+	}
+
+	new(@NonNull String name, @NonNull SymbolKind kind, @NonNull Location location) {
+		this.name = Preconditions.checkNotNull(name, 'name')
+		this.kind = Preconditions.checkNotNull(kind, 'kind')
+		this.location = Preconditions.checkNotNull(location, 'location')
+	}
+
+	new(@NonNull String name, @NonNull SymbolKind kind, @NonNull Location location, String containerName) {
+		this(name, kind, location)
+		this.containerName = containerName
+	}
+}
+
+/**
+ * An event describing a change to a text document. If range and rangeLength are omitted the new text is considered
+ * to be the full content of the document.
+ */
+@JsonRpcData
+class TextDocumentContentChangeEvent {
+	/**
+	 * The range of the document that changed.
+	 */
+	Range range
+
+	/**
+	 * The length of the range that got replaced.
+	 *
+	 * @deprecated Use range instead.
+	 */
+	@Deprecated
+	Integer rangeLength
+
+	/**
+	 * The new text of the range/document.
+	 */
+	@NonNull
+	String text
+
+	new() {
+	}
+
+	new(@NonNull String text) {
+		this.text = Preconditions.checkNotNull(text, 'text')
+	}
+
+	new(Range range, Integer rangeLength, @NonNull String text) {
+		this(text)
+		this.range = range
+		this.rangeLength = rangeLength
+	}
+}
+
+/**
+ * Text documents are identified using an URI. On the protocol level URI's are passed as strings.
+ */
+@JsonRpcData
+class TextDocumentIdentifier {
+	/**
+	 * The text document's uri.
+	 */
+	@NonNull
+	String uri
+
+	new() {
+	}
+
+	new(@NonNull String uri) {
+		this.uri = Preconditions.checkNotNull(uri, 'uri')
+	}
+}
+
+/**
+ * An item to transfer a text document from the client to the server.
+ */
+@JsonRpcData
+class TextDocumentItem {
+	/**
+	 * The text document's uri.
+	 */
+	@NonNull
+	String uri
+
+	/**
+	 * The text document's language identifier
+	 */
+	@NonNull
+	String languageId
+
+	/**
+	 * The version number of this document (it will strictly increase after each change, including undo/redo).
+	 */
+	int version
+
+	/**
+	 * The content of the opened text document.
+	 */
+	@NonNull
+	String text
+
+	new() {
+	}
+
+	new(@NonNull String uri, @NonNull String languageId, int version, @NonNull String text) {
+		this.uri = Preconditions.checkNotNull(uri, 'uri')
+		this.languageId = Preconditions.checkNotNull(languageId, 'languageId')
+		this.version = version
+		this.text = Preconditions.checkNotNull(text, 'text')
+	}
+}
+
+/**
+ * A parameter literal used in requests to pass a text document and a position inside that document.
+ */
+@JsonRpcData
+class TextDocumentPositionParams {
+	/**
+	 * The text document.
+	 */
+	@NonNull
+	TextDocumentIdentifier textDocument
+
+	/**
+	 * Legacy property to support protocol version 1.0 requests.
+	 */
+	@Deprecated
+	String uri
+
+	/**
+	 * The position inside the text document.
+	 */
+	@NonNull
+	Position position
+
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument, @NonNull Position position) {
+		this.textDocument = Preconditions.checkNotNull(textDocument, 'textDocument')
+		this.position = Preconditions.checkNotNull(position, 'position')
+	}
+
+	@Deprecated
+	new(@NonNull TextDocumentIdentifier textDocument, String uri, @NonNull Position position) {
+		this.textDocument = Preconditions.checkNotNull(textDocument, 'textDocument')
+		this.uri = uri
+		this.position = Preconditions.checkNotNull(position, 'position')
+	}
+}
+
+
+/**
+ * The Completion request is sent from the client to the server to compute completion items at a given cursor position.
+ */
+@JsonRpcData
+class CompletionParams extends TextDocumentPositionAndWorkDoneProgressAndPartialResultParams {
+	/**
+	 * The completion context. This is only available if the client specifies
+	 * to send this using {@link CompletionCapabilities#contextSupport} as true.
+	 */
+	CompletionContext context
+
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument, @NonNull Position position) {
+		super(textDocument, position)
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument, @NonNull Position position, CompletionContext context) {
+		this(textDocument, position)
+		this.context = context
+	}
+}
+
+@JsonRpcData
+class CompletionContext {
+	/**
+	 * How the completion was triggered.
+	 */
+	@NonNull
+	CompletionTriggerKind triggerKind
+
+	/**
+	 * The trigger character (a single character) that has trigger code complete.
+	 * Is undefined if {@link #triggerKind} is not {@link CompletionTriggerKind#TriggerCharacter}.
+	 */
+	String triggerCharacter
+
+	new() {
+	}
+
+	new(@NonNull CompletionTriggerKind triggerKind) {
+		this.triggerKind = Preconditions.checkNotNull(triggerKind, 'triggerKind')
+	}
+
+	new(@NonNull CompletionTriggerKind triggerKind, String triggerCharacter) {
+		this(triggerKind)
+		this.triggerCharacter = triggerCharacter
+	}
+}
+
+/**
+ * A textual edit applicable to a text document.
+ */
+@JsonRpcData
+class TextEdit {
+	/**
+	 * The range of the text document to be manipulated. To insert text into a document create a range where start === end.
+	 */
+	@NonNull
+	Range range
+
+	/**
+	 * The string to be inserted. For delete operations use an empty string.
+	 */
+	@NonNull
+	String newText
+
+	new() {
+	}
+
+	new(@NonNull Range range, @NonNull String newText) {
+		this.range = Preconditions.checkNotNull(range, 'range')
+		this.newText = Preconditions.checkNotNull(newText, 'newText')
+	}
+}
+
+/**
+ * Additional information that describes document changes.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class ChangeAnnotation {
+	/**
+	 * A human-readable string describing the actual change. The string
+	 * is rendered prominent in the user interface.
+	 */
+	@NonNull
+	String label
+
+	/**
+	 * A flag which indicates that user confirmation is needed
+	 * before applying the change.
+	 */
+	Boolean needsConfirmation
+
+	/**
+	 * A human-readable string which is rendered less prominent in
+	 * the user interface.
+	 */
+	String description
+
+	new() {
+	}
+
+	new(@NonNull String label) {
+		this.label = Preconditions.checkNotNull(label, 'label')
+	}
+}
+
+/**
+ * A special text edit with an additional change annotation.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class AnnotatedTextEdit extends TextEdit {
+	/**
+	 * The actual annotation identifier
+	 */
+	@NonNull
+	String annotationId
+
+	new() {
+	}
+
+	new(@NonNull Range range, @NonNull String newText, @NonNull String annotationId) {
+		super(range, newText)
+		this.annotationId = Preconditions.checkNotNull(annotationId, 'annotationId')
+	}
+}
+
+/**
+ * A special text edit to provide an insert and a replace operation.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class InsertReplaceEdit {
+	/**
+	 * The string to be inserted.
+	 */
+	@NonNull
+	String newText
+
+	/**
+	 * The range if the insert that is requested
+	 */
+	@NonNull
+	Range insert
+
+	/**
+	 * The range if the replace that is requested.
+	 */
+	@NonNull
+	Range replace
+
+	new() {
+	}
+
+	new(@NonNull String newText, @NonNull Range insert, @NonNull Range replace) {
+		this.newText = Preconditions.checkNotNull(newText, 'newText')
+		this.insert = Preconditions.checkNotNull(insert, 'insert')
+		this.replace = Preconditions.checkNotNull(replace, 'replace')
+	}
+}
+
+/**
+ * An identifier to denote a specific version of a text document. This information usually flows from the client to the server.
+ */
+@JsonRpcData
+@JsonAdapter(VersionedTextDocumentIdentifierTypeAdapter.Factory)
+class VersionedTextDocumentIdentifier extends TextDocumentIdentifier {
+	/**
+	 * The version number of this document. If a versioned text document identifier
+	 * is sent from the server to the client and the file is not open in the editor
+	 * (the server has not received an open notification before) the server can send
+	 * `null` to indicate that the version is known and the content on disk is the
+	 * truth (as specified with document content ownership).
+	 */
+	Integer version
+
+	new() {
+	}
+
+	new(@NonNull String uri, Integer version) {
+		super(uri)
+		this.version = version
+	}
+
+	@Deprecated
+	new(Integer version) {
+		this.version = version
+	}
+}
+
+/**
+ * Describes textual changes on a single text document.
+ * The text document is referred to as a {@link VersionedTextDocumentIdentifier}
+ * to allow clients to check the text document version before an edit is applied.
+ */
+@JsonRpcData
+class TextDocumentEdit {
+	/**
+	 * The text document to change.
+	 */
+	@NonNull
+	VersionedTextDocumentIdentifier textDocument
+
+	/**
+	 * The edits to be applied
+	 */
+	@NonNull
+	List<TextEdit> edits
+
+	new() {
+	}
+
+	new(@NonNull VersionedTextDocumentIdentifier textDocument, @NonNull List<TextEdit> edits) {
+		this.textDocument = Preconditions.checkNotNull(textDocument, 'textDocument')
+		this.edits = Preconditions.checkNotNull(edits, 'edits')
+	}
+}
+
+@JsonRpcData
+@JsonAdapter(ResourceOperationTypeAdapter)
+abstract class ResourceOperation {
+	/**
+	 * The kind of resource operation. For allowed values, see {@link ResourceOperationKind}
+	 */
+	@NonNull
+	String kind
+
+	/**
+	 * An optional annotation identifer describing the operation.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	String annotationId
+
+	new() {
+	}
+
+	new(@NonNull String kind) {
+		this.kind = Preconditions.checkNotNull(kind, 'kind')
+	}
+}
+
+/**
+ * Options to create a file.
+ */
+@JsonRpcData
+class CreateFileOptions {
+	/**
+	 * Overwrite existing file. Overwrite wins over {@link #ignoreIfExists}
+	 */
+	Boolean overwrite
+
+	/**
+	 * Ignore if exists.
+	 */
+	Boolean ignoreIfExists
+
+	new() {
+	}
+
+	new(Boolean overwrite, Boolean ignoreIfExists) {
+		this.overwrite = overwrite
+		this.ignoreIfExists = ignoreIfExists
+	}
+}
+
+/**
+ * Create file operation
+ */
+@JsonRpcData
+class CreateFile extends ResourceOperation {
+	/**
+	 * The resource to create.
+	 */
+	@NonNull
+	String uri
+
+	/**
+	 * Additional options
+	 */
+	CreateFileOptions options
+
+	new() {
+		super(ResourceOperationKind.Create)
+	}
+
+	new(@NonNull String uri) {
+		super(ResourceOperationKind.Create)
+		this.uri = Preconditions.checkNotNull(uri, 'uri')
+	}
+
+	new(@NonNull String uri, CreateFileOptions options) {
+		this(uri)
+		this.options = options
+	}
+}
+
+/**
+ * Rename file options
+ */
+@JsonRpcData
+class RenameFileOptions {
+	/**
+	 * Overwrite target if existing. Overwrite wins over {@link #ignoreIfExists}
+	 */
+	Boolean overwrite
+
+	/**
+	 * Ignores if target exists.
+	 */
+	Boolean ignoreIfExists
+
+	new() {
+	}
+
+	new(Boolean overwrite, Boolean ignoreIfExists) {
+		this.overwrite = overwrite
+		this.ignoreIfExists = ignoreIfExists
+	}
+}
+
+/**
+ * Rename file operation
+ */
+@JsonRpcData
+class RenameFile extends ResourceOperation {
+	/**
+	 * The old (existing) location.
+	 */
+	@NonNull
+	String oldUri
+
+	/**
+	 * The new location.
+	 */
+	@NonNull
+	String newUri
+
+	/**
+	 * Rename options.
+	 */
+	RenameFileOptions options
+
+	new() {
+		super(ResourceOperationKind.Rename)
+	}
+
+	new(@NonNull String oldUri, @NonNull String newUri) {
+		super(ResourceOperationKind.Rename)
+		this.oldUri = Preconditions.checkNotNull(oldUri, 'oldUri')
+		this.newUri = Preconditions.checkNotNull(newUri, 'newUri')
+	}
+
+	new(@NonNull String oldUri, @NonNull String newUri, RenameFileOptions options) {
+		this(oldUri, newUri)
+		this.options = options
+	}
+}
+
+/**
+ * Delete file options
+ */
+@JsonRpcData
+class DeleteFileOptions {
+	/**
+	 * Delete the content recursively if a folder is denoted.
+	 */
+	Boolean recursive
+
+	/**
+	 * Ignore the operation if the file doesn't exist.
+	 */
+	Boolean ignoreIfNotExists
+
+	new() {
+	}
+
+	new(Boolean recursive, Boolean ignoreIfNotExists) {
+		this.recursive = recursive
+		this.ignoreIfNotExists = ignoreIfNotExists
+	}
+}
+
+/**
+ * Delete file operation
+ */
+@JsonRpcData
+class DeleteFile extends ResourceOperation {
+	/**
+	 * The file to delete.
+	 */
+	@NonNull
+	String uri
+
+	/**
+	 * Delete options.
+	 */
+	DeleteFileOptions options
+
+	new() {
+		super(ResourceOperationKind.Delete)
+	}
+
+	new(@NonNull String uri) {
+		super(ResourceOperationKind.Delete)
+		this.uri = Preconditions.checkNotNull(uri, 'uri')
+	}
+
+	new(@NonNull String uri, DeleteFileOptions options) {
+		this(uri)
+		this.options = options
+	}
+}
+
+/**
+ * A resource change.
+ * <p><ul>
+ * <li>If both current and newUri has valid values this is considered to be a move operation.
+ * <li>If current has a valid value while newUri is null it is treated as a delete operation.
+ * <li>If current is null and newUri has a valid value a create operation is executed.
+ * </ul>
+ *
+ * @deprecated As LSP introduces resource operation, use the {@link ResourceOperation} instead.
+ */
+@JsonRpcData
+@Beta
+@Deprecated
+class ResourceChange {
+
+	/**
+	 * The Uri for current resource. Required for delete and move operations
+	 * otherwise it is null.
+	 */
+	String current
+
+	/**
+	 * The new uri for the resource. Required for create and move operations.
+	 * otherwise null.
+	 * <p>
+	 * Must be compatible with the current uri ie. must be a file
+	 * uri if current is not null and is a file uri.
+	 */
+	String newUri
+
+}
+
+/**
+ * A workspace edit represents changes to many resources managed in the workspace.
+ * The edit should either provide {@link #changes} or {@link #documentChanges}.
+ * If documentChanges are present they are preferred over changes
+ * if the client can handle versioned document edits.
+ */
+@JsonRpcData
+class WorkspaceEdit {
+	/**
+	 * Holds changes to existing resources.
+	 */
+	Map<String, List<TextEdit>> changes
+
+	/**
+	 * Depending on the client capability
+	 * {@link WorkspaceEditCapabilities#resourceOperations} document changes are either
+	 * an array of {@link TextDocumentEdit}s to express changes to n different text
+	 * documents where each text document edit addresses a specific version of
+	 * a text document. Or it can contain above {@link TextDocumentEdit}s mixed with
+	 * create, rename and delete file / folder operations.
+	 * <p>
+	 * Whether a client supports versioned document edits is expressed via
+	 * {@link WorkspaceEditCapabilities#documentChanges} client capability.
+	 * <p>
+	 * If a client neither supports {@link WorkspaceEditCapabilities#documentChanges} nor
+	 * {@link WorkspaceEditCapabilities#resourceOperations} then only plain {@link TextEdit}s
+	 * using the {@link #changes} property are supported.
+	 */
+	@JsonAdapter(DocumentChangeListAdapter)
+	List<Either<TextDocumentEdit, ResourceOperation>> documentChanges
+
+	/**
+	 * If resource changes are supported the `WorkspaceEdit`
+	 * uses the property `resourceChanges` which are either a
+	 * rename, move, delete or content change.
+	 * <p>
+	 * These changes are applied in the order that they are supplied,
+	 * however clients may group the changes for optimization
+	 *
+	 * @deprecated Since LSP introduces resource operations, use the {@link #documentChanges} instead
+	 */
+	@Beta
+	@JsonAdapter(ResourceChangeListAdapter)
+	@Deprecated
+	List<Either<ResourceChange, TextDocumentEdit>> resourceChanges
+
+	/**
+	 * A map of change annotations that can be referenced in
+	 * {@link AnnotatedTextEdit}s or {@link ResourceOperation}s.
+	 * <p>
+	 * Client support depends on {@link WorkspaceEditCapabilities#changeAnnotationSupport}.
+	 * <p>
+	 * Since 3.16.0
+	 */
+	Map<String, ChangeAnnotation> changeAnnotations
+
+	new() {
+		this.changes = new LinkedHashMap
+	}
+
+	new(Map<String, List<TextEdit>> changes) {
+		this.changes = changes
+	}
+
+	new(List<Either<TextDocumentEdit, ResourceOperation>> documentChanges) {
+		this.documentChanges = documentChanges
+	}
+}
+
+
+/**
+ * The options of a Workspace Symbol Request.
+ */
+@JsonRpcData
+class WorkspaceSymbolOptions extends AbstractWorkDoneProgressOptions {
+
+}
+
+/**
+ * The options of a Workspace Symbol Registration Request.
+ */
+@JsonRpcData
+class WorkspaceSymbolRegistrationOptions extends WorkspaceSymbolOptions {
+}
+
+
+/**
+ * The parameters of a Workspace Symbol Request.
+ */
+@JsonRpcData
+class WorkspaceSymbolParams extends WorkDoneProgressAndPartialResultParams {
+	/**
+	 * A query string to filter symbols by. Clients may send an empty
+	 * string here to request all symbols.
+	 */
+	@NonNull
+	String query
+
+	new() {
+	}
+
+	new(@NonNull String query) {
+		this.query = Preconditions.checkNotNull(query, 'query')
+	}
+}
+
+/**
+ * General parameters to register for a capability.
+ */
+@JsonRpcData
+class Registration {
+	/**
+	 * The id used to register the request. The id can be used to deregister
+	 * the request again.
+	 */
+	@NonNull
+	String id
+
+	/**
+	 * The method / capability to register for.
+	 */
+	@NonNull
+	String method
+
+	/**
+	 * Options necessary for the registration.
+	 */
+	@JsonAdapter(JsonElementTypeAdapter.Factory)
+	Object registerOptions
+
+	new() {
+	}
+
+	new(@NonNull String id, @NonNull String method) {
+		this.id = Preconditions.checkNotNull(id, 'id')
+		this.method = Preconditions.checkNotNull(method, 'method')
+	}
+
+	new(@NonNull String id, @NonNull String method, Object registerOptions) {
+		this(id, method)
+		this.registerOptions = registerOptions
+	}
+}
+
+/**
+ * The client/registerCapability request is sent from the server to the client to register
+ * for a new capability on the client side. Not all clients need to support dynamic
+ * capability registration. A client opts in via the dynamicRegistration property on the
+ * specific client capabilities. A client can even provide dynamic registration for
+ * capability A but not for capability B (see TextDocumentClientCapabilities as an example).
+ */
+@JsonRpcData
+class RegistrationParams {
+	@NonNull
+	List<Registration> registrations
+
+	new() {
+		this(new ArrayList)
+	}
+
+	new(@NonNull List<Registration> registrations) {
+		this.registrations = Preconditions.checkNotNull(registrations, 'registrations')
+	}
+}
+
+/**
+ * A document filter denotes a document through properties like language, schema or pattern.
+ */
+@JsonRpcData
+class DocumentFilter {
+	/**
+	 * A language id, like `typescript`.
+	 */
+	String language
+
+	/**
+	 * A uri scheme, like `file` or `untitled`.
+	 */
+	String scheme
+
+	/**
+	 * A glob pattern, like `*.{ts,js}`.
+	 */
+	String pattern
+
+	new() {
+	}
+
+	new(String language, String scheme, String pattern) {
+		this.language = language
+		this.scheme = scheme
+		this.pattern = pattern
+	}
+}
+
+/**
+ * Since most of the registration options require to specify a document selector there is
+ * a base interface that can be used.
+ */
+@JsonRpcData
+class TextDocumentRegistrationOptions {
+	/**
+	 * A document selector to identify the scope of the registration. If set to null
+	 * the document selector provided on the client side will be used.
+	 */
+	List<DocumentFilter> documentSelector
+
+	new() {
+	}
+
+	new(List<DocumentFilter> documentSelector) {
+		this.documentSelector = documentSelector
+	}
+}
+
+/**
+ * General parameters to unregister a capability.
+ */
+@JsonRpcData
+class Unregistration {
+	/**
+	 * The id used to unregister the request or notification. Usually an id
+	 * provided during the register request.
+	 */
+	@NonNull
+	String id
+
+	/**
+	 * The method / capability to unregister for.
+	 */
+	@NonNull
+	String method
+
+	new() {
+	}
+
+	new(@NonNull String id, @NonNull String method) {
+		this.id = Preconditions.checkNotNull(id, 'id')
+		this.method = Preconditions.checkNotNull(method, 'method')
+	}
+}
+
+/**
+ * The client/unregisterCapability request is sent from the server to the client to unregister
+ * a previously registered capability.
+ */
+@JsonRpcData
+class UnregistrationParams {
+	// This is a known misspelling in the spec and is intended to be fixed in LSP 4.x
+	@NonNull
+	List<Unregistration> unregisterations
+
+	new() {
+		this(new ArrayList)
+	}
+
+	new(@NonNull List<Unregistration> unregisterations) {
+		this.unregisterations = Preconditions.checkNotNull(unregisterations, 'unregisterations')
+	}
+}
+
+/**
+ * Describe options to be used when registered for text document change events.
+ */
+@JsonRpcData
+class TextDocumentChangeRegistrationOptions extends TextDocumentRegistrationOptions {
+	/**
+	 * How documents are synced to the server. See TextDocumentSyncKind.Full
+	 * and TextDocumentSyncKind.Incremental.
+	 */
+	@NonNull
+	TextDocumentSyncKind syncKind
+
+	new() {
+	}
+
+	new(@NonNull TextDocumentSyncKind syncKind) {
+		this.syncKind = Preconditions.checkNotNull(syncKind, 'syncKind')
+	}
+}
+
+@JsonRpcData
+class TextDocumentSaveRegistrationOptions extends TextDocumentRegistrationOptions {
+	/**
+	 * The client is supposed to include the content on save.
+	 */
+	Boolean includeText
+
+	new() {
+	}
+
+	new(Boolean includeText) {
+		this.includeText = includeText
+	}
+}
+
+@JsonRpcData
+class CompletionRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+	/**
+	 * Most tools trigger completion request automatically without explicitly requesting
+	 * it using a keyboard shortcut (e.g. Ctrl+Space). Typically they do so when the user
+	 * starts to type an identifier. For example if the user types `c` in a JavaScript file
+	 * code complete will automatically pop up present `console` besides others as a
+	 * completion item. Characters that make up identifiers don't need to be listed here.
+	 * <p>
+	 * If code complete should automatically be trigger on characters not being valid inside
+	 * an identifier (for example `.` in JavaScript) list them in `triggerCharacters`.
+	 */
+	List<String> triggerCharacters
+
+	/**
+	 * The server provides support to resolve additional information for a completion item.
+	 */
+	Boolean resolveProvider
+
+	/**
+	 * The list of all possible characters that commit a completion. This field
+	 * can be used if clients don't support individual commit characters per
+	 * completion item. See client capability
+	 * {@link CompletionItemCapabilities#commitCharactersSupport}.
+	 * <p>
+	 * If a server provides both {@code allCommitCharacters} and commit characters on
+	 * an individual completion item the ones on the completion item win.
+	 * <p>
+	 * Since 3.2.0
+	 */
+	List<String> allCommitCharacters
+
+	new() {
+	}
+
+	new(List<String> triggerCharacters, Boolean resolveProvider) {
+		this.triggerCharacters = triggerCharacters
+		this.resolveProvider = resolveProvider
+	}
+}
+
+@JsonRpcData
+class SignatureHelpRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+	/**
+	 * The characters that trigger signature help automatically.
+	 */
+	List<String> triggerCharacters
+
+	/**
+	 * List of characters that re-trigger signature help.
+	 * <p>
+	 * These trigger characters are only active when signature help is already showing. All trigger characters
+	 * are also counted as re-trigger characters.
+	 * <p>
+	 * Since 3.15.0
+	 */
+	List<String> retriggerCharacters
+
+	new() {
+	}
+
+	new(List<String> triggerCharacters) {
+		this.triggerCharacters = triggerCharacters
+	}
+
+	new(List<String> triggerCharacters, List<String> retriggerCharacters) {
+		this(triggerCharacters)
+		this.retriggerCharacters = retriggerCharacters
+	}
+}
+
+@JsonRpcData
+class CodeLensRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+	/**
+	 * Code lens has a resolve provider as well.
+	 */
+	Boolean resolveProvider
+
+	new() {
+	}
+
+	new(Boolean resolveProvider) {
+		this.resolveProvider = resolveProvider
+	}
+}
+
+@JsonRpcData
+class DocumentLinkRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+	/**
+	 * Document links have a resolve provider as well.
+	 */
+	Boolean resolveProvider
+
+	new() {
+	}
+
+	new(Boolean resolveProvider) {
+		this.resolveProvider = resolveProvider
+	}
+}
+
+@JsonRpcData
+class DocumentOnTypeFormattingRegistrationOptions extends TextDocumentRegistrationOptions {
+	/**
+	 * A character on which formatting should be triggered, like `}`.
+	 */
+	@NonNull
+	String firstTriggerCharacter
+
+	/**
+	 * More trigger characters.
+	 */
+	List<String> moreTriggerCharacter
+
+	new() {
+	}
+
+	new(@NonNull String firstTriggerCharacter) {
+		this.firstTriggerCharacter = Preconditions.checkNotNull(firstTriggerCharacter, 'firstTriggerCharacter')
+	}
+
+	new(@NonNull String firstTriggerCharacter, List<String> moreTriggerCharacter) {
+		this(firstTriggerCharacter)
+		this.moreTriggerCharacter = moreTriggerCharacter
+	}
+}
+
+/**
+ * The workspace/executeCommand request is sent from the client to the server to trigger command
+ * execution on the server. In most cases the server creates a WorkspaceEdit structure and applies
+ * the changes to the workspace using the request workspace/applyEdit which is sent from the server
+ * to the client.
+ */
+@JsonRpcData
+class ExecuteCommandParams implements WorkDoneProgressParams {
+	/**
+	 * An optional token that a server can use to report work done progress.
+	 */
+	Either<String, Integer> workDoneToken
+
+	/**
+	 * The identifier of the actual command handler.
+	 */
+	@NonNull
+	String command
+
+	/**
+	 * Arguments that the command should be invoked with.
+	 * The arguments are typically specified when a command is returned from the server to the client.
+	 * Example requests that return a command are textDocument/codeAction or textDocument/codeLens.
+	 */
+	List<Object> arguments
+
+	new() {
+	}
+
+	new(@NonNull String command, List<Object> arguments) {
+		this.command = Preconditions.checkNotNull(command, 'command')
+		this.arguments = arguments
+	}
+
+	new(@NonNull String command, List<Object> arguments, Either<String, Integer> workDoneToken) {
+		this(command, arguments)
+		this.workDoneToken = workDoneToken
+	}
+}
+
+/**
+ * Execute command registration options.
+ */
+@JsonRpcData
+class ExecuteCommandRegistrationOptions extends ExecuteCommandOptions {
+}
+
+/**
+ * The workspace/applyEdit request is sent from the server to the client to modify resource on the client side.
+ */
+@JsonRpcData
+class ApplyWorkspaceEditParams {
+	/**
+	 * The edits to apply.
+	 */
+	@NonNull
+	WorkspaceEdit edit
+
+	/**
+	 * An optional label of the workspace edit. This label is
+	 * presented in the user interface for example on an undo
+	 * stack to undo the workspace edit.
+	 */
+	String label
+
+	new() {
+	}
+
+	new(@NonNull WorkspaceEdit edit) {
+		this.edit = Preconditions.checkNotNull(edit, 'edit')
+	}
+
+	new(@NonNull WorkspaceEdit edit, String label) {
+		this(edit)
+		this.label = label
+	}
+}
+
+@JsonRpcData
+class ApplyWorkspaceEditResponse {
+	/**
+	 * Indicates whether the edit was applied or not.
+	 */
+	boolean applied
+
+	/**
+	 * An optional textual description for why the edit was not applied.
+	 * This may be used by the server for diagnostic logging or to provide
+	 * a suitable error for a request that triggered the edit.
+	 */
+	String failureReason
+
+	/**
+	 * Depending on the client's failure handling strategy `failedChange`
+	 * might contain the index of the change that failed. This property is
+	 * only available if the client signals a {@link WorkspaceEditCapabilities#failureHandling}
+	 * strategy in its client capabilities.
+	 */
+	Integer failedChange
+
+	new() {
+	}
+
+	new(boolean applied) {
+		this.applied = applied
+	}
+}
+
+/**
+ * The server supports workspace folder.
+ * <p>
+ * Since 3.6.0
+ */
+@JsonRpcData
+class WorkspaceFoldersOptions {
+	/**
+	 * The server has support for workspace folders
+	 */
+	Boolean supported
+
+	/**
+	 * Whether the server wants to receive workspace folder
+	 * change notifications.
+	 * <p>
+	 * If a string is provided, the string is treated as an ID
+	 * under which the notification is registered on the client
+	 * side. The ID can be used to unregister for these events
+	 * using the `client/unregisterCapability` request.
+	 */
+	Either<String, Boolean> changeNotifications
+}
+
+/**
+ * The workspace/workspaceFolders request is sent from the server to the client to fetch
+ * the current open list of workspace folders. Returns null in the response if only a single
+ * file is open in the tool. Returns an empty array if a workspace is open but no folders
+ * are configured.
+ */
+@JsonRpcData
+class WorkspaceFolder {
+	/**
+	 * The associated URI for this workspace folder.
+	 */
+	@NonNull String uri
+
+	/**
+	 * The name of the workspace folder. Defaults to the uri's basename.
+	 */
+	String name
+
+	new() {
+	}
+
+	new(@NonNull String uri) {
+		this.uri = Preconditions.checkNotNull(uri, 'uri')
+	}
+
+	new(@NonNull String uri, String name) {
+		this(uri)
+		this.name = name
+	}
+}
+
+/**
+ * The workspace folder change event.
+ * <p>
+ * Since 3.6.0
+ */
+@JsonRpcData
+class WorkspaceFoldersChangeEvent {
+	/**
+	 * The array of added workspace folders
+	 */
+	@NonNull
+	List<WorkspaceFolder> added = new ArrayList
+
+	/**
+	 * The array of the removed workspace folders
+	 */
+	@NonNull
+	List<WorkspaceFolder> removed = new ArrayList
+
+	new() {
+	}
+
+	new(@NonNull List<WorkspaceFolder> added, @NonNull List<WorkspaceFolder> removed) {
+		this.added = Preconditions.checkNotNull(added, 'added')
+		this.removed = Preconditions.checkNotNull(removed, 'removed')
+	}
+}
+
+/**
+ * The workspace/didChangeWorkspaceFolders notification is sent from the client to the server to
+ * inform the server about workspace folder configuration changes. The notification is sent by
+ * default if both ServerCapabilities/workspace/workspaceFolders and
+ * ClientCapabilities/workspace/workspaceFolders are true; or if the server has registered to
+ * receive this notification it first.
+ * <p>
+ * Since 3.6.0
+ */
+@JsonRpcData
+class DidChangeWorkspaceFoldersParams {
+	/**
+	 * The actual workspace folder change event.
+	 */
+	@NonNull
+	WorkspaceFoldersChangeEvent event
+
+	new() {
+	}
+
+	new(@NonNull WorkspaceFoldersChangeEvent event) {
+		this.event = Preconditions.checkNotNull(event, 'event')
+	}
+}
+
+/**
+ * The server is interested in file notifications/requests.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class FileOperationsServerCapabilities {
+	/**
+	 * The server is interested in receiving didCreateFiles notifications.
+	 */
+	FileOperationOptions didCreate
+
+	/**
+	 * The server is interested in receiving willCreateFiles requests.
+	 */
+	FileOperationOptions willCreate
+
+	/**
+	 * The server is interested in receiving didRenameFiles notifications.
+	 */
+	FileOperationOptions didRename
+
+	/**
+	 * The server is interested in receiving willRenameFiles requests.
+	 */
+	FileOperationOptions willRename
+
+	/**
+	 * The server is interested in receiving didDeleteFiles file notifications.
+	 */
+	FileOperationOptions didDelete
+
+	/**
+	 * The server is interested in receiving willDeleteFiles file requests.
+	 */
+	FileOperationOptions willDelete
+
+	new() {
+	}
+}
+
+/**
+ * The options for file operations.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class FileOperationOptions {
+	/**
+	 * The actual filters.
+	 */
+	@NonNull
+	List<FileOperationFilter> filters = new ArrayList
+
+	new() {
+	}
+
+	new(@NonNull List<FileOperationFilter> filters) {
+		this.filters = Preconditions.checkNotNull(filters, 'filters')
+	}
+}
+
+/**
+ * A filter to describe in which file operation requests or notifications
+ * the server is interested in.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class FileOperationFilter {
+	/**
+	 * The actual file operation pattern.
+	 */
+	@NonNull
+	FileOperationPattern pattern
+
+	/**
+	 * A Uri like {@code file} or {@code untitled}.
+	 */
+	String scheme
+
+	new() {
+	}
+
+	new(@NonNull FileOperationPattern pattern) {
+		this.pattern = Preconditions.checkNotNull(pattern, 'pattern')
+	}
+
+	new(@NonNull FileOperationPattern pattern, String scheme) {
+		this(pattern)
+		this.scheme = scheme
+	}
+}
+
+/**
+ * A pattern to describe in which file operation requests or notifications
+ * the server is interested in.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class FileOperationPattern {
+	/**
+	 * The glob pattern to match. Glob patterns can have the following syntax:
+	 * <ul>
+	 * <li>`*` to match one or more characters in a path segment
+	 * <li>`?` to match on one character in a path segment
+	 * <li>`**` to match any number of path segments, including none
+	 * <li>`{}` to group sub patterns into an OR expression. (e.g. `**​/*.{ts,js}` matches all TypeScript and JavaScript files)
+	 * <li>`[]` to declare a range of characters to match in a path segment (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)
+	 * <li>`[!...]` to negate a range of characters to match in a path segment (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not `example.0`)
+	 * </ul>
+	 */
+	@NonNull
+	String glob
+
+	/**
+	 * Whether to match files or folders with this pattern.
+	 * <p>
+	 * Matches both if undefined.
+	 * <p>
+	 * See {@link FileOperationPatternKind} for allowed values.
+	 */
+	String matches
+
+	/**
+	 * Additional options used during matching.
+	 */
+	FileOperationPatternOptions options
+
+	new() {
+	}
+
+	new(@NonNull String glob) {
+		this.glob = Preconditions.checkNotNull(glob, 'glob')
+	}
+}
+
+/**
+ * Matching options for the file operation pattern.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class FileOperationPatternOptions {
+	/**
+	 * The pattern should be matched ignoring casing.
+	 */
+	Boolean ignoreCase
+
+	new() {
+	}
+
+	new(Boolean ignoreCase) {
+		this.ignoreCase = ignoreCase
+	}
+}
+
+/**
+ * The parameters sent in notifications/requests for user-initiated creation
+ * of files.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class CreateFilesParams {
+	/**
+	 * An array of all files/folders created in this operation.
+	 */
+	@NonNull
+	List<FileCreate> files = new ArrayList
+
+	new() {
+	}
+
+	new(@NonNull List<FileCreate> files) {
+		this.files = Preconditions.checkNotNull(files, 'files')
+	}
+}
+
+/**
+ * Represents information on a file/folder create.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class FileCreate {
+	/**
+	 * A file:// URI for the location of the file/folder being created.
+	 */
+	@NonNull
+	String uri
+
+	new() {
+	}
+
+	new(@NonNull String uri) {
+		this.uri = Preconditions.checkNotNull(uri, 'uri')
+	}
+}
+
+/**
+ * The parameters sent in notifications/requests for user-initiated renames
+ * of files.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class RenameFilesParams {
+	/**
+	 * An array of all files/folders renamed in this operation. When a folder
+	 * is renamed, only the folder will be included, and not its children.
+	 */
+	@NonNull
+	List<FileRename> files = new ArrayList
+
+	new() {
+	}
+
+	new(@NonNull List<FileRename> files) {
+		this.files = Preconditions.checkNotNull(files, 'files')
+	}
+}
+
+/**
+ * Represents information on a file/folder rename.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class FileRename {
+	/**
+	 * A file:// URI for the original location of the file/folder being renamed.
+	 */
+	@NonNull
+	String oldUri
+
+	/**
+	 * A file:// URI for the new location of the file/folder being renamed.
+	 */
+	@NonNull
+	String newUri
+
+	new() {
+	}
+
+	new(@NonNull String oldUri, @NonNull String newUri) {
+		this.oldUri = Preconditions.checkNotNull(oldUri, 'oldUri')
+		this.newUri = Preconditions.checkNotNull(newUri, 'newUri')
+	}
+}
+
+/**
+ * The parameters sent in notifications/requests for user-initiated deletes
+ * of files.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class DeleteFilesParams {
+	/**
+	 * An array of all files/folders deleted in this operation.
+	 */
+	@NonNull
+	List<FileDelete> files = new ArrayList
+
+	new() {
+	}
+
+	new(@NonNull List<FileDelete> files) {
+		this.files = Preconditions.checkNotNull(files, 'files')
+	}
+}
+
+/**
+ * Represents information on a file/folder delete.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class FileDelete {
+	/**
+	 * A file:// URI for the location of the file/folder being deleted.
+	 */
+	@NonNull
+	String uri
+
+	new() {
+	}
+
+	new(@NonNull String uri) {
+		this.uri = Preconditions.checkNotNull(uri, 'uri')
+	}
+}
+
+/**
+ * The workspace/configuration request is sent from the server to the client to fetch configuration
+ * settings from the client. The request can fetch several configuration settings in one roundtrip.
+ * The order of the returned configuration settings correspond to the order of the passed
+ * {@link ConfigurationItem}s (e.g. the first item in the response is the result for the first
+ * configuration item in the params).
+ * <p>
+ * Since 3.6.0
+ */
+@JsonRpcData
+class ConfigurationParams {
+	@NonNull
+	List<ConfigurationItem> items
+
+	new() {
+	}
+
+	new(@NonNull List<ConfigurationItem> items) {
+		this.items = Preconditions.checkNotNull(items, 'items')
+	}
+}
+
+/**
+ * A ConfigurationItem consist of the configuration section to ask for and an additional scope URI.
+ * The configuration section asked for is defined by the server and doesn’t necessarily need to
+ * correspond to the configuration store used by the client. So a server might ask for a configuration
+ * {@code cpp.formatterOptions} but the client stores the configuration in an XML store layout differently.
+ * It is up to the client to do the necessary conversion. If a scope URI is provided the client
+ * should return the setting scoped to the provided resource. If the client for example uses
+ * EditorConfig to manage its settings the configuration should be returned for the passed resource
+ * URI. If the client can't provide a configuration setting for a given scope then null needs to be
+ * present in the returned array.
+ * <p>
+ * Since 3.6.0
+ */
+@JsonRpcData
+class ConfigurationItem {
+	/**
+	 * The scope to get the configuration section for.
+	 */
+	String scopeUri
+
+	/**
+	 * The configuration section asked for.
+	 */
+	String section
+}
+
+/**
+ * The document color request is sent from the client to the server to list all color references
+ * found in a given text document. Along with the range, a color value in RGB is returned.
+ * <p>
+ * Since 3.6.0
+ */
+@JsonRpcData
+class DocumentColorParams extends WorkDoneProgressAndPartialResultParams {
+	/**
+	 * The text document.
+	 */
+	@NonNull
+	TextDocumentIdentifier textDocument
+
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument) {
+		this.textDocument = Preconditions.checkNotNull(textDocument, 'textDocument')
+	}
+}
+
+@JsonRpcData
+class ColorInformation {
+	/**
+	 * The range in the document where this color appears.
+	 */
+	@NonNull
+	Range range
+
+	/**
+	 * The actual color value for this color range.
+	 */
+	@NonNull
+	Color color
+
+	new() {
+	}
+
+	new(@NonNull Range range, @NonNull Color color) {
+		this.range = Preconditions.checkNotNull(range, 'range')
+		this.color = Preconditions.checkNotNull(color, 'color')
+	}
+}
+
+/**
+ * Represents a color in RGBA space.
+ */
+@JsonRpcData
+class Color {
+	/**
+	 * The red component of this color in the range [0-1].
+	 */
+	double red
+
+	/**
+	 * The green component of this color in the range [0-1].
+	 */
+	double green
+
+	/**
+	 * The blue component of this color in the range [0-1].
+	 */
+	double blue
+
+	/**
+	 * The alpha component of this color in the range [0-1].
+	 */
+	double alpha
+
+	new() {
+	}
+
+	new(double red, double green, double blue, double alpha) {
+		this.red = red
+		this.green = green
+		this.blue = blue
+		this.alpha = alpha
+	}
+}
+
+/**
+ * The color presentation request is sent from the client to the server to obtain a list of presentations
+ * for a color value at a given location.
+ * <p>
+ * Since 3.6.0
+ */
+@JsonRpcData
+class ColorPresentationParams extends WorkDoneProgressAndPartialResultParams {
+	/**
+	 * The text document.
+	 */
+	@NonNull
+	TextDocumentIdentifier textDocument
+
+	/**
+	 * The color information to request presentations for.
+	 */
+	@NonNull
+	Color color
+
+	/**
+	 * The range where the color would be inserted. Serves as a context.
+	 */
+	@NonNull
+	Range range
+
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument, @NonNull Color color, @NonNull Range range) {
+		this.textDocument = Preconditions.checkNotNull(textDocument, 'textDocument')
+		this.color = Preconditions.checkNotNull(color, 'color')
+		this.range = Preconditions.checkNotNull(range, 'range')
+	}
+}
+
+@JsonRpcData
+class ColorPresentation {
+	/**
+	 * The label of this color presentation. It will be shown on the color
+	 * picker header. By default this is also the text that is inserted when selecting
+	 * this color presentation.
+	 */
+	@NonNull
+	String label
+
+	/**
+	 * An edit which is applied to a document when selecting
+	 * this presentation for the color. When `null` the label is used.
+	 */
+	TextEdit textEdit
+
+	/**
+	 * An optional array of additional text edits that are applied when
+	 * selecting this color presentation. Edits must not overlap with the main edit nor with themselves.
+	 */
+	List<TextEdit> additionalTextEdits
+
+	new() {
+	}
+
+	new(@NonNull String label) {
+		this.label = Preconditions.checkNotNull(label, 'label')
+	}
+
+	new(@NonNull String label, TextEdit textEdit) {
+		this(label)
+		this.textEdit = textEdit
+	}
+
+	new(@NonNull String label, TextEdit textEdit, List<TextEdit> additionalTextEdits) {
+		this(label)
+		this.textEdit = textEdit
+		this.additionalTextEdits = additionalTextEdits
+	}
+}
+
+/**
+ * The folding range request is sent from the client to the server to return all folding
+ * ranges found in a given text document.
+ */
+@JsonRpcData
+class FoldingRangeRequestParams extends WorkDoneProgressAndPartialResultParams {
+	/**
+	 * The text document.
+	 */
+	@NonNull
+	TextDocumentIdentifier textDocument
+
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument) {
+		this.textDocument = Preconditions.checkNotNull(textDocument, 'textDocument')
+	}
+}
+
+/**
+ * Represents a folding range.
+ */
+@JsonRpcData
+class FoldingRange {
+
+	/**
+	 * The zero-based line number from where the folded range starts.
+	 */
+	int startLine
+
+	/**
+	 * The zero-based line number where the folded range ends.
+	 */
+	int endLine
+
+	/**
+	 * The zero-based character offset from where the folded range starts. If not defined, defaults
+	 * to the length of the start line.
+	 */
+	Integer startCharacter
+
+	/**
+	 * The zero-based character offset before the folded range ends. If not defined, defaults to the
+	 * length of the end line.
+	 */
+	Integer endCharacter
+
+	/**
+	 * Describes the kind of the folding range such as {@link FoldingRangeKind#Comment} or {@link FoldingRangeKind#Region}.
+	 * The kind is used to categorize folding ranges and used by commands like 'Fold all comments'.
+	 * See {@link FoldingRangeKind} for an enumeration of standardized kinds.
+	 */
+	String kind
+
+	new() {
+	}
+
+	new(int startLine, int endLine) {
+		this.startLine = startLine
+		this.endLine = endLine
+	}
+}
+
+/**
+ * The parameter of a `textDocument/prepareCallHierarchy` request.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class CallHierarchyPrepareParams extends TextDocumentPositionAndWorkDoneProgressParams {
+
+}
+
+/**
+ * The parameter of a `callHierarchy/incomingCalls` request.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class CallHierarchyIncomingCallsParams extends WorkDoneProgressAndPartialResultParams {
+	@NonNull
+	CallHierarchyItem item
+
+	new() {
+	}
+
+	new(@NonNull CallHierarchyItem item) {
+		this.item = Preconditions.checkNotNull(item, 'item')
+	}
+}
+
+/**
+ * The parameter of a `callHierarchy/outgoingCalls` request.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class CallHierarchyOutgoingCallsParams extends WorkDoneProgressAndPartialResultParams {
+	@NonNull
+	CallHierarchyItem item
+
+	new() {
+	}
+
+	new(@NonNull CallHierarchyItem item) {
+		this.item = Preconditions.checkNotNull(item, 'item')
+	}
+}
+
+/**
+ * Represents an incoming call, e.g. a caller of a method or constructor.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class CallHierarchyIncomingCall {
+	/**
+	 * The item that makes the call.
+	 */
+	@NonNull
+	CallHierarchyItem from
+
+	/**
+	 * The range at which at which the calls appears. This is relative to the caller
+	 * denoted by {@link #from}.
+	 */
+	@NonNull
+	List<Range> fromRanges
+
+	new() {
+	}
+
+	new(@NonNull CallHierarchyItem from, @NonNull List<Range> fromRanges) {
+		this.from = Preconditions.checkNotNull(from, 'from')
+		this.fromRanges = Preconditions.checkNotNull(fromRanges, 'fromRanges')
+	}
+}
+
+/**
+ * Represents an outgoing call, e.g. calling a getter from a method or a method from a constructor etc.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class CallHierarchyOutgoingCall {
+	/**
+	 * The item that is called.
+	 */
+	@NonNull
+	CallHierarchyItem to
+
+	/**
+	 * The range at which this item is called. This is the range relative to the caller, i.e. the {@link CallHierarchyOutgoingCallsParams#item}.
+	 */
+	@NonNull
+	List<Range> fromRanges
+
+	new() {
+	}
+
+	new(@NonNull CallHierarchyItem to, @NonNull List<Range> fromRanges) {
+		this.to = Preconditions.checkNotNull(to, 'to')
+		this.fromRanges = Preconditions.checkNotNull(fromRanges, 'fromRanges')
+	}
+}
+
+/**
+ * The result of a {@code textDocument/prepareCallHierarchy} request.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class CallHierarchyItem {
+	/**
+	 * The name of the item targeted by the call hierarchy request.
+	 */
+	@NonNull
+	String name
+
+	/**
+	 * More detail for this item, e.g the signature of a function.
+	 */
+	String detail
+
+	/**
+	 * The kind of this item.
+	 */
+	@NonNull
+	SymbolKind kind
+
+	/**
+	 * Tags for this item.
+	 */
+	List<SymbolTag> tags
+
+	/**
+	 * The resource identifier of this item.
+	 */
+	@NonNull
+	String uri
+
+	/**
+	 * The range enclosing this symbol not including leading/trailing whitespace but everything else
+	 * like comments. This information is typically used to determine if the the clients cursor is
+	 * inside the symbol to reveal in the symbol in the UI.
+	 */
+	@NonNull
+	Range range
+
+	/**
+	 * The range that should be selected and revealed when this symbol is being picked, e.g the name of a function.
+	 * Must be contained by the the {@link CallHierarchyItem#getRange range}.
+	 */
+	@NonNull
+	Range selectionRange
+
+	/**
+	 * A data entry field that is preserved between a call hierarchy prepare and
+	 * incoming calls or outgoing calls requests.
+	 */
+	@JsonAdapter(JsonElementTypeAdapter.Factory)
+	Object data
+}
+
+/**
+ * A parameter literal used in selection range requests.
+ * <p>
+ * Since 3.15.0
+ */
+@JsonRpcData
+class SelectionRangeParams extends WorkDoneProgressAndPartialResultParams {
+	/**
+	 * The text document.
+	 */
+	@NonNull
+	TextDocumentIdentifier textDocument
+
+	/**
+	 * The positions inside the text document.
+	 */
+	@NonNull
+	List<Position> positions
+
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument, @NonNull List<Position> positions) {
+		this.textDocument = Preconditions.checkNotNull(textDocument, 'textDocument')
+		this.positions = Preconditions.checkNotNull(positions, 'positions')
+	}
+}
+
+/**
+ * Selection range options.
+ * <p>
+ * Since 3.15.0
+ */
+@JsonRpcData
+class SelectionRangeOptions extends AbstractWorkDoneProgressOptions {
+}
+
+/**
+ * Selection range registration options.
+ * <p>
+ * Since 3.15.0
+ */
+@JsonRpcData
+class SelectionRangeRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+	/**
+	 * The id used to register the request. The id can be used to deregister
+	 * the request again. See also Registration#id.
+	 */
+	String id
+
+	new() {
+	}
+
+	new(String id) {
+		this.id = id
+	}
+}
+
+/**
+ * A selection range represents a part of a selection hierarchy. A selection range
+ * may have a parent selection range that contains it.
+ * <p>
+ * Since 3.15.0
+ */
+@JsonRpcData
+class SelectionRange {
+
+	/**
+	 * The range of this selection range.
+	 */
+	@NonNull
+	Range range
+
+	/**
+	 * The parent selection range containing this range. Therefore `parent.range` must contain {@link #range}.
+	 */
+	SelectionRange parent
+
+	new() {
+	}
+
+	new(@NonNull Range range, SelectionRange parent) {
+		this.range = Preconditions.checkNotNull(range, 'range')
+		this.parent = parent
+	}
+}
+
+/**
+ * Hover options.
+ */
+@JsonRpcData
+class HoverOptions extends AbstractWorkDoneProgressOptions {
+}
+
+/**
+ * Hover registration options.
+ */
+@JsonRpcData
+class HoverRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+}
+
+/**
+ * The hover request is sent from the client to the server to request hover information at a given
+ * text document position.
+ */
+@JsonRpcData
+class HoverParams extends TextDocumentPositionAndWorkDoneProgressParams {
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument, @NonNull Position position) {
+		super(textDocument, position)
+	}
+}
+
+@JsonRpcData
+class DeclarationOptions extends AbstractWorkDoneProgressOptions {
+}
+
+@JsonRpcData
+class DeclarationRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+	/**
+	 * The id used to register the request. The id can be used to deregister
+	 * the request again. See also Registration#id.
+	 */
+	String id
+
+	new() {
+	}
+
+	new(String id) {
+		this.id = id
+	}
+}
+
+/**
+ * The go to declaration request is sent from the client to the server to resolve the declaration
+ * location of a symbol at a given text document position.
+ */
+@JsonRpcData
+class DeclarationParams extends TextDocumentPositionAndWorkDoneProgressAndPartialResultParams {
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument, @NonNull Position position) {
+		super(textDocument, position)
+	}
+}
+
+@JsonRpcData
+class DefinitionOptions extends AbstractWorkDoneProgressOptions {
+}
+
+@JsonRpcData
+class DefinitionRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+}
+
+/**
+ * The go to definition request is sent from the client to the server to resolve the definition
+ * location of a symbol at a given text document position.
+ */
+@JsonRpcData
+class DefinitionParams extends TextDocumentPositionAndWorkDoneProgressAndPartialResultParams {
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument, @NonNull Position position) {
+		super(textDocument, position)
+	}
+}
+
+@JsonRpcData
+class TypeDefinitionOptions extends AbstractWorkDoneProgressOptions {
+}
+
+@JsonRpcData
+class TypeDefinitionRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+	/**
+	 * The id used to register the request. The id can be used to deregister
+	 * the request again. See also Registration#id.
+	 */
+	String id
+
+	new() {
+	}
+
+	new(String id) {
+		this.id = id
+	}
+}
+
+/**
+ * The go to type definition request is sent from the client to the server to resolve the type definition
+ * location of a symbol at a given text document position.
+ */
+@JsonRpcData
+class TypeDefinitionParams extends TextDocumentPositionAndWorkDoneProgressAndPartialResultParams {
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument, @NonNull Position position) {
+		super(textDocument, position)
+	}
+}
+
+@JsonRpcData
+class ImplementationOptions extends AbstractWorkDoneProgressOptions {
+}
+
+@JsonRpcData
+class ImplementationRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+	/**
+	 * The id used to register the request. The id can be used to deregister
+	 * the request again. See also Registration#id.
+	 */
+	String id
+
+	new() {
+	}
+
+	new(String id) {
+		this.id = id
+	}
+}
+
+/**
+ * The go to implementation request is sent from the client to the server to resolve the implementation
+ * location of a symbol at a given text document position.
+ */
+@JsonRpcData
+class ImplementationParams extends TextDocumentPositionAndWorkDoneProgressAndPartialResultParams {
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument, @NonNull Position position) {
+		super(textDocument, position)
+	}
+}
+
+@JsonRpcData
+class DocumentHighlightOptions extends AbstractWorkDoneProgressOptions {
+}
+
+@JsonRpcData
+class DocumentHighlightRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+}
+
+/**
+ * The document highlight request is sent from the client to the server to resolve a document highlights
+ * for a given text document position.
+ */
+@JsonRpcData
+class DocumentHighlightParams extends TextDocumentPositionAndWorkDoneProgressAndPartialResultParams {
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument, @NonNull Position position) {
+		super(textDocument, position)
+	}
+}
+
+/**
+ * The prepare rename request is sent from the client to the server to setup and test the validity of a
+ * rename operation at a given location.
+ */
+@JsonRpcData
+class PrepareRenameParams extends TextDocumentPositionParams {
+	new() {
+	}
+
+	new(@NonNull TextDocumentIdentifier textDocument, @NonNull Position position) {
+		super(textDocument, position)
+	}
+}
+
+/**
+ * Moniker options.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class MonikerOptions extends AbstractWorkDoneProgressOptions {
+}
+
+/**
+ * Moniker registration options.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class MonikerRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+}
+
+/**
+ * The moniker request is sent from the client to the server to get the symbol monikers for a given text document position.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class MonikerParams extends TextDocumentPositionAndWorkDoneProgressAndPartialResultParams {
+}
+
+/**
+ * Moniker definition to match LSIF 0.5 moniker definition.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class Moniker {
+	/**
+	 * The scheme of the moniker. For example tsc or .Net
+	 */
+	@NonNull
+	String scheme
+
+	/**
+	 * The identifier of the moniker. The value is opaque in LSIF however
+	 * schema owners are allowed to define the structure if they want.
+	 */
+	@NonNull
+	String identifier
+
+	/**
+	 * The scope in which the moniker is unique. Values are taken from {@link UniquenessLevel}.
+	 */
+	@NonNull
+	String unique
+
+	/**
+	 * The moniker kind if known. Values are taken from {@link MonikerKind}.
+	 */
+	String kind
+
+	new() {
+	}
+
+	new(@NonNull String scheme, @NonNull String identifier, @NonNull String unique) {
+		this.scheme = Preconditions.checkNotNull(scheme, 'scheme')
+		this.identifier = Preconditions.checkNotNull(identifier, 'identifier')
+		this.unique = Preconditions.checkNotNull(unique, 'unique')
+	}
+
+	new(@NonNull String scheme, @NonNull String identifier, @NonNull String unique, String kind) {
+		this(scheme, identifier, unique)
+		this.kind = kind
+	}
+}
+
+/**
+ * The {@code window/workDoneProgress/create} request is sent from the server to the client to ask the client to create a work done progress.
+ */
+@JsonRpcData
+class WorkDoneProgressCreateParams {
+	/**
+	 * The token to be used to report progress.
+	 */
+	@NonNull
+	Either<String, Integer> token
+
+	new() {
+	}
+
+	new(@NonNull Either<String, Integer> token) {
+		this.token = Preconditions.checkNotNull(token, 'token')
+	}
+}
+
+/**
+ * The {@code window/workDoneProgress/cancel} notification is sent from the client to the server to cancel a progress initiated on the server side using the
+ * {@code window/workDoneProgress/create}.
+ */
+@JsonRpcData
+class WorkDoneProgressCancelParams {
+	/**
+	 * The token to be used to report progress.
+	 */
+	@NonNull
+	Either<String, Integer> token
+
+	new() {
+	}
+
+	new(@NonNull Either<String, Integer> token) {
+		this.token = Preconditions.checkNotNull(token, 'token')
+	}
+}
+
+/**
+ * Params to show a document.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class ShowDocumentParams {
+	/**
+	 * The document uri to show.
+	 */
+	@NonNull
+	String uri
+
+	/**
+	 * Indicates to show the resource in an external program.
+	 * To show for example <a href="https://www.eclipse.org/">
+	 * https://www.eclipse.org/</a>
+	 * in the default WEB browser set to {@code true}.
+	 */
+	Boolean external
+
+	/**
+	 * An optional property to indicate whether the editor
+	 * showing the document should take focus or not.
+	 * Clients might ignore this property if an external
+	 * program is started.
+	 */
+	Boolean takeFocus
+
+	/**
+	 * An optional selection range if the document is a text
+	 * document. Clients might ignore the property if an
+	 * external program is started or the file is not a text
+	 * file.
+	 */
+	Range selection
+
+	new() {
+	}
+
+	new(@NonNull String uri) {
+		this.uri = Preconditions.checkNotNull(uri, 'uri')
+	}
+}
+
+/**
+ * The result of an show document request.
+ * <p>
+ * Since 3.16.0
+ */
+@JsonRpcData
+class ShowDocumentResult {
+	/**
+	 * A boolean indicating if the show was successful.
+	 */
+	boolean success
+
+	new() {
+	}
+
+	new(boolean success) {
+		this.success = success
+	}
+}
diff --git a/java/org/eclipse/lsp4j/ProtocolExtensions.xtend b/java/org/eclipse/lsp4j/ProtocolExtensions.xtend
new file mode 100644
index 0000000..8d83646
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ProtocolExtensions.xtend
@@ -0,0 +1,13 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j
+
diff --git a/java/org/eclipse/lsp4j/PublishDiagnosticsCapabilities.java b/java/org/eclipse/lsp4j/PublishDiagnosticsCapabilities.java
new file mode 100644
index 0000000..2117a08
--- /dev/null
+++ b/java/org/eclipse/lsp4j/PublishDiagnosticsCapabilities.java
@@ -0,0 +1,269 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DiagnosticsTagSupport;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to `textDocument/publishDiagnostics`.
+ */
+@SuppressWarnings("all")
+public class PublishDiagnosticsCapabilities {
+  /**
+   * Whether the client accepts diagnostics with related information.
+   */
+  private Boolean relatedInformation;
+  
+  /**
+   * Client supports the tag property to provide meta data about a diagnostic.
+   * Clients supporting tags have to handle unknown tags gracefully.
+   * <p>
+   * This property had been added and implemented as boolean before it was
+   * added to the specification as {@link DiagnosticsTagSupport}. In order to
+   * keep this implementation compatible with intermediate clients (including
+   * vscode-language-client &lt; 6.0.0) we add an either type here.
+   * <p>
+   * Since 3.15
+   */
+  private Either<Boolean, DiagnosticsTagSupport> tagSupport;
+  
+  /**
+   * Whether the client interprets the version property of the
+   * `textDocument/publishDiagnostics` notification's parameter.
+   * <p>
+   * Since 3.15.0
+   */
+  private Boolean versionSupport;
+  
+  /**
+   * Client supports a codeDescription property
+   * <p>
+   * Since 3.16.0
+   */
+  private Boolean codeDescriptionSupport;
+  
+  /**
+   * Whether code action supports the {@link Diagnostic#data} property which is
+   * preserved between a `textDocument/publishDiagnostics` and
+   * `textDocument/codeAction` request.
+   * <p>
+   * Since 3.16.0
+   */
+  private Boolean dataSupport;
+  
+  public PublishDiagnosticsCapabilities() {
+  }
+  
+  public PublishDiagnosticsCapabilities(final Boolean relatedInformation) {
+    this.relatedInformation = relatedInformation;
+  }
+  
+  public PublishDiagnosticsCapabilities(final Boolean relatedInformation, final DiagnosticsTagSupport tagSupport) {
+    this(relatedInformation);
+    this.setTagSupport(tagSupport);
+  }
+  
+  public PublishDiagnosticsCapabilities(final Boolean relatedInformation, final DiagnosticsTagSupport tagSupport, final Boolean versionSupport) {
+    this(relatedInformation, tagSupport);
+    this.versionSupport = versionSupport;
+  }
+  
+  /**
+   * Whether the client accepts diagnostics with related information.
+   */
+  @Pure
+  public Boolean getRelatedInformation() {
+    return this.relatedInformation;
+  }
+  
+  /**
+   * Whether the client accepts diagnostics with related information.
+   */
+  public void setRelatedInformation(final Boolean relatedInformation) {
+    this.relatedInformation = relatedInformation;
+  }
+  
+  /**
+   * Client supports the tag property to provide meta data about a diagnostic.
+   * Clients supporting tags have to handle unknown tags gracefully.
+   * <p>
+   * This property had been added and implemented as boolean before it was
+   * added to the specification as {@link DiagnosticsTagSupport}. In order to
+   * keep this implementation compatible with intermediate clients (including
+   * vscode-language-client &lt; 6.0.0) we add an either type here.
+   * <p>
+   * Since 3.15
+   */
+  @Pure
+  public Either<Boolean, DiagnosticsTagSupport> getTagSupport() {
+    return this.tagSupport;
+  }
+  
+  /**
+   * Client supports the tag property to provide meta data about a diagnostic.
+   * Clients supporting tags have to handle unknown tags gracefully.
+   * <p>
+   * This property had been added and implemented as boolean before it was
+   * added to the specification as {@link DiagnosticsTagSupport}. In order to
+   * keep this implementation compatible with intermediate clients (including
+   * vscode-language-client &lt; 6.0.0) we add an either type here.
+   * <p>
+   * Since 3.15
+   */
+  public void setTagSupport(final Either<Boolean, DiagnosticsTagSupport> tagSupport) {
+    this.tagSupport = tagSupport;
+  }
+  
+  public void setTagSupport(final Boolean tagSupport) {
+    if (tagSupport == null) {
+      this.tagSupport = null;
+      return;
+    }
+    this.tagSupport = Either.forLeft(tagSupport);
+  }
+  
+  public void setTagSupport(final DiagnosticsTagSupport tagSupport) {
+    if (tagSupport == null) {
+      this.tagSupport = null;
+      return;
+    }
+    this.tagSupport = Either.forRight(tagSupport);
+  }
+  
+  /**
+   * Whether the client interprets the version property of the
+   * `textDocument/publishDiagnostics` notification's parameter.
+   * <p>
+   * Since 3.15.0
+   */
+  @Pure
+  public Boolean getVersionSupport() {
+    return this.versionSupport;
+  }
+  
+  /**
+   * Whether the client interprets the version property of the
+   * `textDocument/publishDiagnostics` notification's parameter.
+   * <p>
+   * Since 3.15.0
+   */
+  public void setVersionSupport(final Boolean versionSupport) {
+    this.versionSupport = versionSupport;
+  }
+  
+  /**
+   * Client supports a codeDescription property
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public Boolean getCodeDescriptionSupport() {
+    return this.codeDescriptionSupport;
+  }
+  
+  /**
+   * Client supports a codeDescription property
+   * <p>
+   * Since 3.16.0
+   */
+  public void setCodeDescriptionSupport(final Boolean codeDescriptionSupport) {
+    this.codeDescriptionSupport = codeDescriptionSupport;
+  }
+  
+  /**
+   * Whether code action supports the {@link Diagnostic#data} property which is
+   * preserved between a `textDocument/publishDiagnostics` and
+   * `textDocument/codeAction` request.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public Boolean getDataSupport() {
+    return this.dataSupport;
+  }
+  
+  /**
+   * Whether code action supports the {@link Diagnostic#data} property which is
+   * preserved between a `textDocument/publishDiagnostics` and
+   * `textDocument/codeAction` request.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setDataSupport(final Boolean dataSupport) {
+    this.dataSupport = dataSupport;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("relatedInformation", this.relatedInformation);
+    b.add("tagSupport", this.tagSupport);
+    b.add("versionSupport", this.versionSupport);
+    b.add("codeDescriptionSupport", this.codeDescriptionSupport);
+    b.add("dataSupport", this.dataSupport);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    PublishDiagnosticsCapabilities other = (PublishDiagnosticsCapabilities) obj;
+    if (this.relatedInformation == null) {
+      if (other.relatedInformation != null)
+        return false;
+    } else if (!this.relatedInformation.equals(other.relatedInformation))
+      return false;
+    if (this.tagSupport == null) {
+      if (other.tagSupport != null)
+        return false;
+    } else if (!this.tagSupport.equals(other.tagSupport))
+      return false;
+    if (this.versionSupport == null) {
+      if (other.versionSupport != null)
+        return false;
+    } else if (!this.versionSupport.equals(other.versionSupport))
+      return false;
+    if (this.codeDescriptionSupport == null) {
+      if (other.codeDescriptionSupport != null)
+        return false;
+    } else if (!this.codeDescriptionSupport.equals(other.codeDescriptionSupport))
+      return false;
+    if (this.dataSupport == null) {
+      if (other.dataSupport != null)
+        return false;
+    } else if (!this.dataSupport.equals(other.dataSupport))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.relatedInformation== null) ? 0 : this.relatedInformation.hashCode());
+    result = prime * result + ((this.tagSupport== null) ? 0 : this.tagSupport.hashCode());
+    result = prime * result + ((this.versionSupport== null) ? 0 : this.versionSupport.hashCode());
+    result = prime * result + ((this.codeDescriptionSupport== null) ? 0 : this.codeDescriptionSupport.hashCode());
+    return prime * result + ((this.dataSupport== null) ? 0 : this.dataSupport.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/PublishDiagnosticsParams.java b/java/org/eclipse/lsp4j/PublishDiagnosticsParams.java
new file mode 100644
index 0000000..fc46851
--- /dev/null
+++ b/java/org/eclipse/lsp4j/PublishDiagnosticsParams.java
@@ -0,0 +1,159 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.lsp4j.Diagnostic;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Diagnostics notification are sent from the server to the client to signal results of validation runs.
+ */
+@SuppressWarnings("all")
+public class PublishDiagnosticsParams {
+  /**
+   * The URI for which diagnostic information is reported.
+   */
+  @NonNull
+  private String uri;
+  
+  /**
+   * An array of diagnostic information items.
+   */
+  @NonNull
+  private List<Diagnostic> diagnostics;
+  
+  /**
+   * Optional the version number of the document the diagnostics are published for.
+   * <p>
+   * Since 3.15.0
+   */
+  private Integer version;
+  
+  public PublishDiagnosticsParams() {
+    ArrayList<Diagnostic> _arrayList = new ArrayList<Diagnostic>();
+    this.diagnostics = _arrayList;
+  }
+  
+  public PublishDiagnosticsParams(@NonNull final String uri, @NonNull final List<Diagnostic> diagnostics) {
+    this.uri = Preconditions.<String>checkNotNull(uri, "uri");
+    this.diagnostics = Preconditions.<List<Diagnostic>>checkNotNull(diagnostics, "diagnostics");
+  }
+  
+  public PublishDiagnosticsParams(@NonNull final String uri, @NonNull final List<Diagnostic> diagnostics, final Integer version) {
+    this(uri, diagnostics);
+    this.version = version;
+  }
+  
+  /**
+   * The URI for which diagnostic information is reported.
+   */
+  @Pure
+  @NonNull
+  public String getUri() {
+    return this.uri;
+  }
+  
+  /**
+   * The URI for which diagnostic information is reported.
+   */
+  public void setUri(@NonNull final String uri) {
+    this.uri = Preconditions.checkNotNull(uri, "uri");
+  }
+  
+  /**
+   * An array of diagnostic information items.
+   */
+  @Pure
+  @NonNull
+  public List<Diagnostic> getDiagnostics() {
+    return this.diagnostics;
+  }
+  
+  /**
+   * An array of diagnostic information items.
+   */
+  public void setDiagnostics(@NonNull final List<Diagnostic> diagnostics) {
+    this.diagnostics = Preconditions.checkNotNull(diagnostics, "diagnostics");
+  }
+  
+  /**
+   * Optional the version number of the document the diagnostics are published for.
+   * <p>
+   * Since 3.15.0
+   */
+  @Pure
+  public Integer getVersion() {
+    return this.version;
+  }
+  
+  /**
+   * Optional the version number of the document the diagnostics are published for.
+   * <p>
+   * Since 3.15.0
+   */
+  public void setVersion(final Integer version) {
+    this.version = version;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("uri", this.uri);
+    b.add("diagnostics", this.diagnostics);
+    b.add("version", this.version);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    PublishDiagnosticsParams other = (PublishDiagnosticsParams) obj;
+    if (this.uri == null) {
+      if (other.uri != null)
+        return false;
+    } else if (!this.uri.equals(other.uri))
+      return false;
+    if (this.diagnostics == null) {
+      if (other.diagnostics != null)
+        return false;
+    } else if (!this.diagnostics.equals(other.diagnostics))
+      return false;
+    if (this.version == null) {
+      if (other.version != null)
+        return false;
+    } else if (!this.version.equals(other.version))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.uri== null) ? 0 : this.uri.hashCode());
+    result = prime * result + ((this.diagnostics== null) ? 0 : this.diagnostics.hashCode());
+    return prime * result + ((this.version== null) ? 0 : this.version.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/Range.java b/java/org/eclipse/lsp4j/Range.java
new file mode 100644
index 0000000..13cc5c6
--- /dev/null
+++ b/java/org/eclipse/lsp4j/Range.java
@@ -0,0 +1,117 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.Position;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A range in a text document expressed as (zero-based) start and end positions.
+ */
+@SuppressWarnings("all")
+public class Range {
+  /**
+   * The range's start position
+   */
+  @NonNull
+  private Position start;
+  
+  /**
+   * The range's end position
+   */
+  @NonNull
+  private Position end;
+  
+  public Range() {
+  }
+  
+  public Range(@NonNull final Position start, @NonNull final Position end) {
+    this.start = Preconditions.<Position>checkNotNull(start, "start");
+    this.end = Preconditions.<Position>checkNotNull(end, "end");
+  }
+  
+  /**
+   * The range's start position
+   */
+  @Pure
+  @NonNull
+  public Position getStart() {
+    return this.start;
+  }
+  
+  /**
+   * The range's start position
+   */
+  public void setStart(@NonNull final Position start) {
+    this.start = Preconditions.checkNotNull(start, "start");
+  }
+  
+  /**
+   * The range's end position
+   */
+  @Pure
+  @NonNull
+  public Position getEnd() {
+    return this.end;
+  }
+  
+  /**
+   * The range's end position
+   */
+  public void setEnd(@NonNull final Position end) {
+    this.end = Preconditions.checkNotNull(end, "end");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("start", this.start);
+    b.add("end", this.end);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    Range other = (Range) obj;
+    if (this.start == null) {
+      if (other.start != null)
+        return false;
+    } else if (!this.start.equals(other.start))
+      return false;
+    if (this.end == null) {
+      if (other.end != null)
+        return false;
+    } else if (!this.end.equals(other.end))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.start== null) ? 0 : this.start.hashCode());
+    return prime * result + ((this.end== null) ? 0 : this.end.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/RangeFormattingCapabilities.java b/java/org/eclipse/lsp4j/RangeFormattingCapabilities.java
new file mode 100644
index 0000000..3682c02
--- /dev/null
+++ b/java/org/eclipse/lsp4j/RangeFormattingCapabilities.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the `textDocument/rangeFormatting`
+ */
+@SuppressWarnings("all")
+public class RangeFormattingCapabilities extends DynamicRegistrationCapabilities {
+  public RangeFormattingCapabilities() {
+  }
+  
+  public RangeFormattingCapabilities(final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ReferenceContext.java b/java/org/eclipse/lsp4j/ReferenceContext.java
new file mode 100644
index 0000000..7c24c00
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ReferenceContext.java
@@ -0,0 +1,78 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The references request is sent from the client to the server to resolve project-wide references for the symbol
+ * denoted by the given text document position.
+ */
+@SuppressWarnings("all")
+public class ReferenceContext {
+  /**
+   * Include the declaration of the current symbol.
+   */
+  private boolean includeDeclaration;
+  
+  public ReferenceContext() {
+  }
+  
+  public ReferenceContext(final boolean includeDeclaration) {
+    this.includeDeclaration = includeDeclaration;
+  }
+  
+  /**
+   * Include the declaration of the current symbol.
+   */
+  @Pure
+  public boolean isIncludeDeclaration() {
+    return this.includeDeclaration;
+  }
+  
+  /**
+   * Include the declaration of the current symbol.
+   */
+  public void setIncludeDeclaration(final boolean includeDeclaration) {
+    this.includeDeclaration = includeDeclaration;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("includeDeclaration", this.includeDeclaration);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ReferenceContext other = (ReferenceContext) obj;
+    if (other.includeDeclaration != this.includeDeclaration)
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + (this.includeDeclaration ? 1231 : 1237);
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ReferenceOptions.java b/java/org/eclipse/lsp4j/ReferenceOptions.java
new file mode 100644
index 0000000..745b3c0
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ReferenceOptions.java
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class ReferenceOptions extends AbstractWorkDoneProgressOptions {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ReferenceParams.java b/java/org/eclipse/lsp4j/ReferenceParams.java
new file mode 100644
index 0000000..001b2d0
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ReferenceParams.java
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.Position;
+import org.eclipse.lsp4j.ReferenceContext;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.TextDocumentPositionAndWorkDoneProgressAndPartialResultParams;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The references request is sent from the client to the server to resolve project-wide references for the symbol
+ * denoted by the given text document position.
+ */
+@SuppressWarnings("all")
+public class ReferenceParams extends TextDocumentPositionAndWorkDoneProgressAndPartialResultParams {
+  @NonNull
+  private ReferenceContext context;
+  
+  public ReferenceParams() {
+  }
+  
+  public ReferenceParams(@NonNull final TextDocumentIdentifier textDocument, @NonNull final Position position, @NonNull final ReferenceContext context) {
+    super(textDocument, position);
+    this.context = Preconditions.<ReferenceContext>checkNotNull(context, "context");
+  }
+  
+  @Deprecated
+  public ReferenceParams(@NonNull final ReferenceContext context) {
+    this.context = Preconditions.<ReferenceContext>checkNotNull(context, "context");
+  }
+  
+  @Pure
+  @NonNull
+  public ReferenceContext getContext() {
+    return this.context;
+  }
+  
+  public void setContext(@NonNull final ReferenceContext context) {
+    this.context = Preconditions.checkNotNull(context, "context");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("context", this.context);
+    b.add("partialResultToken", getPartialResultToken());
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("textDocument", getTextDocument());
+    b.add("uri", getUri());
+    b.add("position", getPosition());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    ReferenceParams other = (ReferenceParams) obj;
+    if (this.context == null) {
+      if (other.context != null)
+        return false;
+    } else if (!this.context.equals(other.context))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.context== null) ? 0 : this.context.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ReferenceRegistrationOptions.java b/java/org/eclipse/lsp4j/ReferenceRegistrationOptions.java
new file mode 100644
index 0000000..effc73d
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ReferenceRegistrationOptions.java
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractTextDocumentRegistrationAndWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class ReferenceRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ReferencesCapabilities.java b/java/org/eclipse/lsp4j/ReferencesCapabilities.java
new file mode 100644
index 0000000..f5d2115
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ReferencesCapabilities.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the `textDocument/references`
+ */
+@SuppressWarnings("all")
+public class ReferencesCapabilities extends DynamicRegistrationCapabilities {
+  public ReferencesCapabilities() {
+  }
+  
+  public ReferencesCapabilities(final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/Registration.java b/java/org/eclipse/lsp4j/Registration.java
new file mode 100644
index 0000000..cac0657
--- /dev/null
+++ b/java/org/eclipse/lsp4j/Registration.java
@@ -0,0 +1,154 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import com.google.gson.annotations.JsonAdapter;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * General parameters to register for a capability.
+ */
+@SuppressWarnings("all")
+public class Registration {
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again.
+   */
+  @NonNull
+  private String id;
+  
+  /**
+   * The method / capability to register for.
+   */
+  @NonNull
+  private String method;
+  
+  /**
+   * Options necessary for the registration.
+   */
+  @JsonAdapter(JsonElementTypeAdapter.Factory.class)
+  private Object registerOptions;
+  
+  public Registration() {
+  }
+  
+  public Registration(@NonNull final String id, @NonNull final String method) {
+    this.id = Preconditions.<String>checkNotNull(id, "id");
+    this.method = Preconditions.<String>checkNotNull(method, "method");
+  }
+  
+  public Registration(@NonNull final String id, @NonNull final String method, final Object registerOptions) {
+    this(id, method);
+    this.registerOptions = registerOptions;
+  }
+  
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again.
+   */
+  @Pure
+  @NonNull
+  public String getId() {
+    return this.id;
+  }
+  
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again.
+   */
+  public void setId(@NonNull final String id) {
+    this.id = Preconditions.checkNotNull(id, "id");
+  }
+  
+  /**
+   * The method / capability to register for.
+   */
+  @Pure
+  @NonNull
+  public String getMethod() {
+    return this.method;
+  }
+  
+  /**
+   * The method / capability to register for.
+   */
+  public void setMethod(@NonNull final String method) {
+    this.method = Preconditions.checkNotNull(method, "method");
+  }
+  
+  /**
+   * Options necessary for the registration.
+   */
+  @Pure
+  public Object getRegisterOptions() {
+    return this.registerOptions;
+  }
+  
+  /**
+   * Options necessary for the registration.
+   */
+  public void setRegisterOptions(final Object registerOptions) {
+    this.registerOptions = registerOptions;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("id", this.id);
+    b.add("method", this.method);
+    b.add("registerOptions", this.registerOptions);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    Registration other = (Registration) obj;
+    if (this.id == null) {
+      if (other.id != null)
+        return false;
+    } else if (!this.id.equals(other.id))
+      return false;
+    if (this.method == null) {
+      if (other.method != null)
+        return false;
+    } else if (!this.method.equals(other.method))
+      return false;
+    if (this.registerOptions == null) {
+      if (other.registerOptions != null)
+        return false;
+    } else if (!this.registerOptions.equals(other.registerOptions))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.id== null) ? 0 : this.id.hashCode());
+    result = prime * result + ((this.method== null) ? 0 : this.method.hashCode());
+    return prime * result + ((this.registerOptions== null) ? 0 : this.registerOptions.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/RegistrationParams.java b/java/org/eclipse/lsp4j/RegistrationParams.java
new file mode 100644
index 0000000..465a0da
--- /dev/null
+++ b/java/org/eclipse/lsp4j/RegistrationParams.java
@@ -0,0 +1,83 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.lsp4j.Registration;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The client/registerCapability request is sent from the server to the client to register
+ * for a new capability on the client side. Not all clients need to support dynamic
+ * capability registration. A client opts in via the dynamicRegistration property on the
+ * specific client capabilities. A client can even provide dynamic registration for
+ * capability A but not for capability B (see TextDocumentClientCapabilities as an example).
+ */
+@SuppressWarnings("all")
+public class RegistrationParams {
+  @NonNull
+  private List<Registration> registrations;
+  
+  public RegistrationParams() {
+    this(new ArrayList<Registration>());
+  }
+  
+  public RegistrationParams(@NonNull final List<Registration> registrations) {
+    this.registrations = Preconditions.<List<Registration>>checkNotNull(registrations, "registrations");
+  }
+  
+  @Pure
+  @NonNull
+  public List<Registration> getRegistrations() {
+    return this.registrations;
+  }
+  
+  public void setRegistrations(@NonNull final List<Registration> registrations) {
+    this.registrations = Preconditions.checkNotNull(registrations, "registrations");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("registrations", this.registrations);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    RegistrationParams other = (RegistrationParams) obj;
+    if (this.registrations == null) {
+      if (other.registrations != null)
+        return false;
+    } else if (!this.registrations.equals(other.registrations))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.registrations== null) ? 0 : this.registrations.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/RegularExpressionsCapabilities.java b/java/org/eclipse/lsp4j/RegularExpressionsCapabilities.java
new file mode 100644
index 0000000..4d5fa5c
--- /dev/null
+++ b/java/org/eclipse/lsp4j/RegularExpressionsCapabilities.java
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Client capabilities specific to regular expressions.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class RegularExpressionsCapabilities {
+  /**
+   * The engine's name.
+   */
+  @NonNull
+  private String engine;
+  
+  /**
+   * The engine's version.
+   */
+  private String version;
+  
+  public RegularExpressionsCapabilities() {
+  }
+  
+  public RegularExpressionsCapabilities(@NonNull final String engine) {
+    this.engine = Preconditions.<String>checkNotNull(engine, "engine");
+  }
+  
+  public RegularExpressionsCapabilities(@NonNull final String engine, final String version) {
+    this(engine);
+    this.version = version;
+  }
+  
+  /**
+   * The engine's name.
+   */
+  @Pure
+  @NonNull
+  public String getEngine() {
+    return this.engine;
+  }
+  
+  /**
+   * The engine's name.
+   */
+  public void setEngine(@NonNull final String engine) {
+    this.engine = Preconditions.checkNotNull(engine, "engine");
+  }
+  
+  /**
+   * The engine's version.
+   */
+  @Pure
+  public String getVersion() {
+    return this.version;
+  }
+  
+  /**
+   * The engine's version.
+   */
+  public void setVersion(final String version) {
+    this.version = version;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("engine", this.engine);
+    b.add("version", this.version);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    RegularExpressionsCapabilities other = (RegularExpressionsCapabilities) obj;
+    if (this.engine == null) {
+      if (other.engine != null)
+        return false;
+    } else if (!this.engine.equals(other.engine))
+      return false;
+    if (this.version == null) {
+      if (other.version != null)
+        return false;
+    } else if (!this.version.equals(other.version))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.engine== null) ? 0 : this.engine.hashCode());
+    return prime * result + ((this.version== null) ? 0 : this.version.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/RenameCapabilities.java b/java/org/eclipse/lsp4j/RenameCapabilities.java
new file mode 100644
index 0000000..2649555
--- /dev/null
+++ b/java/org/eclipse/lsp4j/RenameCapabilities.java
@@ -0,0 +1,185 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.lsp4j.PrepareSupportDefaultBehavior;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the `textDocument/rename`
+ */
+@SuppressWarnings("all")
+public class RenameCapabilities extends DynamicRegistrationCapabilities {
+  /**
+   * Client supports testing for validity of rename operations
+   * before execution.
+   * <p>
+   * Since 3.12.0
+   */
+  private Boolean prepareSupport;
+  
+  /**
+   * Client supports the default behavior result ({@code &#123; defaultBehavior: boolean &#125;}).
+   * <p>
+   * The value indicates the default behavior used by the client.
+   * <p>
+   * Since 3.16.0
+   */
+  private PrepareSupportDefaultBehavior prepareSupportDefaultBehavior;
+  
+  /**
+   * Whether the client honors the change annotations in
+   * text edits and resource operations returned via the
+   * rename request's workspace edit by for example presenting
+   * the workspace edit in the user interface and asking
+   * for confirmation.
+   * <p>
+   * Since 3.16.0
+   */
+  private Boolean honorsChangeAnnotations;
+  
+  public RenameCapabilities() {
+  }
+  
+  public RenameCapabilities(final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+  }
+  
+  public RenameCapabilities(final Boolean prepareSupport, final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+    this.prepareSupport = prepareSupport;
+  }
+  
+  /**
+   * Client supports testing for validity of rename operations
+   * before execution.
+   * <p>
+   * Since 3.12.0
+   */
+  @Pure
+  public Boolean getPrepareSupport() {
+    return this.prepareSupport;
+  }
+  
+  /**
+   * Client supports testing for validity of rename operations
+   * before execution.
+   * <p>
+   * Since 3.12.0
+   */
+  public void setPrepareSupport(final Boolean prepareSupport) {
+    this.prepareSupport = prepareSupport;
+  }
+  
+  /**
+   * Client supports the default behavior result ({@code &#123; defaultBehavior: boolean &#125;}).
+   * <p>
+   * The value indicates the default behavior used by the client.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public PrepareSupportDefaultBehavior getPrepareSupportDefaultBehavior() {
+    return this.prepareSupportDefaultBehavior;
+  }
+  
+  /**
+   * Client supports the default behavior result ({@code &#123; defaultBehavior: boolean &#125;}).
+   * <p>
+   * The value indicates the default behavior used by the client.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setPrepareSupportDefaultBehavior(final PrepareSupportDefaultBehavior prepareSupportDefaultBehavior) {
+    this.prepareSupportDefaultBehavior = prepareSupportDefaultBehavior;
+  }
+  
+  /**
+   * Whether the client honors the change annotations in
+   * text edits and resource operations returned via the
+   * rename request's workspace edit by for example presenting
+   * the workspace edit in the user interface and asking
+   * for confirmation.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public Boolean getHonorsChangeAnnotations() {
+    return this.honorsChangeAnnotations;
+  }
+  
+  /**
+   * Whether the client honors the change annotations in
+   * text edits and resource operations returned via the
+   * rename request's workspace edit by for example presenting
+   * the workspace edit in the user interface and asking
+   * for confirmation.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setHonorsChangeAnnotations(final Boolean honorsChangeAnnotations) {
+    this.honorsChangeAnnotations = honorsChangeAnnotations;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("prepareSupport", this.prepareSupport);
+    b.add("prepareSupportDefaultBehavior", this.prepareSupportDefaultBehavior);
+    b.add("honorsChangeAnnotations", this.honorsChangeAnnotations);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    RenameCapabilities other = (RenameCapabilities) obj;
+    if (this.prepareSupport == null) {
+      if (other.prepareSupport != null)
+        return false;
+    } else if (!this.prepareSupport.equals(other.prepareSupport))
+      return false;
+    if (this.prepareSupportDefaultBehavior == null) {
+      if (other.prepareSupportDefaultBehavior != null)
+        return false;
+    } else if (!this.prepareSupportDefaultBehavior.equals(other.prepareSupportDefaultBehavior))
+      return false;
+    if (this.honorsChangeAnnotations == null) {
+      if (other.honorsChangeAnnotations != null)
+        return false;
+    } else if (!this.honorsChangeAnnotations.equals(other.honorsChangeAnnotations))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.prepareSupport== null) ? 0 : this.prepareSupport.hashCode());
+    result = prime * result + ((this.prepareSupportDefaultBehavior== null) ? 0 : this.prepareSupportDefaultBehavior.hashCode());
+    return prime * result + ((this.honorsChangeAnnotations== null) ? 0 : this.honorsChangeAnnotations.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/RenameFile.java b/java/org/eclipse/lsp4j/RenameFile.java
new file mode 100644
index 0000000..1c1a33c
--- /dev/null
+++ b/java/org/eclipse/lsp4j/RenameFile.java
@@ -0,0 +1,157 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.RenameFileOptions;
+import org.eclipse.lsp4j.ResourceOperation;
+import org.eclipse.lsp4j.ResourceOperationKind;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Rename file operation
+ */
+@SuppressWarnings("all")
+public class RenameFile extends ResourceOperation {
+  /**
+   * The old (existing) location.
+   */
+  @NonNull
+  private String oldUri;
+  
+  /**
+   * The new location.
+   */
+  @NonNull
+  private String newUri;
+  
+  /**
+   * Rename options.
+   */
+  private RenameFileOptions options;
+  
+  public RenameFile() {
+    super(ResourceOperationKind.Rename);
+  }
+  
+  public RenameFile(@NonNull final String oldUri, @NonNull final String newUri) {
+    super(ResourceOperationKind.Rename);
+    this.oldUri = Preconditions.<String>checkNotNull(oldUri, "oldUri");
+    this.newUri = Preconditions.<String>checkNotNull(newUri, "newUri");
+  }
+  
+  public RenameFile(@NonNull final String oldUri, @NonNull final String newUri, final RenameFileOptions options) {
+    this(oldUri, newUri);
+    this.options = options;
+  }
+  
+  /**
+   * The old (existing) location.
+   */
+  @Pure
+  @NonNull
+  public String getOldUri() {
+    return this.oldUri;
+  }
+  
+  /**
+   * The old (existing) location.
+   */
+  public void setOldUri(@NonNull final String oldUri) {
+    this.oldUri = Preconditions.checkNotNull(oldUri, "oldUri");
+  }
+  
+  /**
+   * The new location.
+   */
+  @Pure
+  @NonNull
+  public String getNewUri() {
+    return this.newUri;
+  }
+  
+  /**
+   * The new location.
+   */
+  public void setNewUri(@NonNull final String newUri) {
+    this.newUri = Preconditions.checkNotNull(newUri, "newUri");
+  }
+  
+  /**
+   * Rename options.
+   */
+  @Pure
+  public RenameFileOptions getOptions() {
+    return this.options;
+  }
+  
+  /**
+   * Rename options.
+   */
+  public void setOptions(final RenameFileOptions options) {
+    this.options = options;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("oldUri", this.oldUri);
+    b.add("newUri", this.newUri);
+    b.add("options", this.options);
+    b.add("kind", getKind());
+    b.add("annotationId", getAnnotationId());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    RenameFile other = (RenameFile) obj;
+    if (this.oldUri == null) {
+      if (other.oldUri != null)
+        return false;
+    } else if (!this.oldUri.equals(other.oldUri))
+      return false;
+    if (this.newUri == null) {
+      if (other.newUri != null)
+        return false;
+    } else if (!this.newUri.equals(other.newUri))
+      return false;
+    if (this.options == null) {
+      if (other.options != null)
+        return false;
+    } else if (!this.options.equals(other.options))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.oldUri== null) ? 0 : this.oldUri.hashCode());
+    result = prime * result + ((this.newUri== null) ? 0 : this.newUri.hashCode());
+    return prime * result + ((this.options== null) ? 0 : this.options.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/RenameFileOptions.java b/java/org/eclipse/lsp4j/RenameFileOptions.java
new file mode 100644
index 0000000..54383f8
--- /dev/null
+++ b/java/org/eclipse/lsp4j/RenameFileOptions.java
@@ -0,0 +1,110 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Rename file options
+ */
+@SuppressWarnings("all")
+public class RenameFileOptions {
+  /**
+   * Overwrite target if existing. Overwrite wins over {@link #ignoreIfExists}
+   */
+  private Boolean overwrite;
+  
+  /**
+   * Ignores if target exists.
+   */
+  private Boolean ignoreIfExists;
+  
+  public RenameFileOptions() {
+  }
+  
+  public RenameFileOptions(final Boolean overwrite, final Boolean ignoreIfExists) {
+    this.overwrite = overwrite;
+    this.ignoreIfExists = ignoreIfExists;
+  }
+  
+  /**
+   * Overwrite target if existing. Overwrite wins over {@link #ignoreIfExists}
+   */
+  @Pure
+  public Boolean getOverwrite() {
+    return this.overwrite;
+  }
+  
+  /**
+   * Overwrite target if existing. Overwrite wins over {@link #ignoreIfExists}
+   */
+  public void setOverwrite(final Boolean overwrite) {
+    this.overwrite = overwrite;
+  }
+  
+  /**
+   * Ignores if target exists.
+   */
+  @Pure
+  public Boolean getIgnoreIfExists() {
+    return this.ignoreIfExists;
+  }
+  
+  /**
+   * Ignores if target exists.
+   */
+  public void setIgnoreIfExists(final Boolean ignoreIfExists) {
+    this.ignoreIfExists = ignoreIfExists;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("overwrite", this.overwrite);
+    b.add("ignoreIfExists", this.ignoreIfExists);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    RenameFileOptions other = (RenameFileOptions) obj;
+    if (this.overwrite == null) {
+      if (other.overwrite != null)
+        return false;
+    } else if (!this.overwrite.equals(other.overwrite))
+      return false;
+    if (this.ignoreIfExists == null) {
+      if (other.ignoreIfExists != null)
+        return false;
+    } else if (!this.ignoreIfExists.equals(other.ignoreIfExists))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.overwrite== null) ? 0 : this.overwrite.hashCode());
+    return prime * result + ((this.ignoreIfExists== null) ? 0 : this.ignoreIfExists.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/RenameFilesParams.java b/java/org/eclipse/lsp4j/RenameFilesParams.java
new file mode 100644
index 0000000..1bf8f2d
--- /dev/null
+++ b/java/org/eclipse/lsp4j/RenameFilesParams.java
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.lsp4j.FileRename;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The parameters sent in notifications/requests for user-initiated renames
+ * of files.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class RenameFilesParams {
+  /**
+   * An array of all files/folders renamed in this operation. When a folder
+   * is renamed, only the folder will be included, and not its children.
+   */
+  @NonNull
+  private List<FileRename> files = new ArrayList<FileRename>();
+  
+  public RenameFilesParams() {
+  }
+  
+  public RenameFilesParams(@NonNull final List<FileRename> files) {
+    this.files = Preconditions.<List<FileRename>>checkNotNull(files, "files");
+  }
+  
+  /**
+   * An array of all files/folders renamed in this operation. When a folder
+   * is renamed, only the folder will be included, and not its children.
+   */
+  @Pure
+  @NonNull
+  public List<FileRename> getFiles() {
+    return this.files;
+  }
+  
+  /**
+   * An array of all files/folders renamed in this operation. When a folder
+   * is renamed, only the folder will be included, and not its children.
+   */
+  public void setFiles(@NonNull final List<FileRename> files) {
+    this.files = Preconditions.checkNotNull(files, "files");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("files", this.files);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    RenameFilesParams other = (RenameFilesParams) obj;
+    if (this.files == null) {
+      if (other.files != null)
+        return false;
+    } else if (!this.files.equals(other.files))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.files== null) ? 0 : this.files.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/RenameOptions.java b/java/org/eclipse/lsp4j/RenameOptions.java
new file mode 100644
index 0000000..397f3e7
--- /dev/null
+++ b/java/org/eclipse/lsp4j/RenameOptions.java
@@ -0,0 +1,131 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractTextDocumentRegistrationAndWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Rename options
+ */
+@SuppressWarnings("all")
+public class RenameOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   * 
+   * @deprecated This options object is not specified for StaticRegistrationOptions
+   */
+  @Deprecated
+  private String id;
+  
+  /**
+   * Renames should be checked and tested before being executed.
+   */
+  private Boolean prepareProvider;
+  
+  public RenameOptions() {
+  }
+  
+  @Deprecated
+  public RenameOptions(final String id) {
+    this.id = id;
+  }
+  
+  public RenameOptions(final Boolean prepareProvider) {
+    this.prepareProvider = prepareProvider;
+  }
+  
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   * 
+   * @deprecated This options object is not specified for StaticRegistrationOptions
+   */
+  @Pure
+  @Deprecated
+  public String getId() {
+    return this.id;
+  }
+  
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   * 
+   * @deprecated This options object is not specified for StaticRegistrationOptions
+   */
+  @Deprecated
+  public void setId(final String id) {
+    this.id = id;
+  }
+  
+  /**
+   * Renames should be checked and tested before being executed.
+   */
+  @Pure
+  public Boolean getPrepareProvider() {
+    return this.prepareProvider;
+  }
+  
+  /**
+   * Renames should be checked and tested before being executed.
+   */
+  public void setPrepareProvider(final Boolean prepareProvider) {
+    this.prepareProvider = prepareProvider;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("id", this.id);
+    b.add("prepareProvider", this.prepareProvider);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    RenameOptions other = (RenameOptions) obj;
+    if (this.id == null) {
+      if (other.id != null)
+        return false;
+    } else if (!this.id.equals(other.id))
+      return false;
+    if (this.prepareProvider == null) {
+      if (other.prepareProvider != null)
+        return false;
+    } else if (!this.prepareProvider.equals(other.prepareProvider))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.id== null) ? 0 : this.id.hashCode());
+    return prime * result + ((this.prepareProvider== null) ? 0 : this.prepareProvider.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/RenameParams.java b/java/org/eclipse/lsp4j/RenameParams.java
new file mode 100644
index 0000000..c226410
--- /dev/null
+++ b/java/org/eclipse/lsp4j/RenameParams.java
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.Position;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.TextDocumentPositionAndWorkDoneProgressParams;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The rename request is sent from the client to the server to do a workspace wide rename of a symbol.
+ */
+@SuppressWarnings("all")
+public class RenameParams extends TextDocumentPositionAndWorkDoneProgressParams {
+  /**
+   * The new name of the symbol. If the given name is not valid the request must return a
+   * ResponseError with an appropriate message set.
+   */
+  @NonNull
+  private String newName;
+  
+  public RenameParams() {
+  }
+  
+  public RenameParams(@NonNull final TextDocumentIdentifier textDocument, @NonNull final Position position, @NonNull final String newName) {
+    super(textDocument, position);
+    this.newName = Preconditions.<String>checkNotNull(newName, "newName");
+  }
+  
+  /**
+   * The new name of the symbol. If the given name is not valid the request must return a
+   * ResponseError with an appropriate message set.
+   */
+  @Pure
+  @NonNull
+  public String getNewName() {
+    return this.newName;
+  }
+  
+  /**
+   * The new name of the symbol. If the given name is not valid the request must return a
+   * ResponseError with an appropriate message set.
+   */
+  public void setNewName(@NonNull final String newName) {
+    this.newName = Preconditions.checkNotNull(newName, "newName");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("newName", this.newName);
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("textDocument", getTextDocument());
+    b.add("uri", getUri());
+    b.add("position", getPosition());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    RenameParams other = (RenameParams) obj;
+    if (this.newName == null) {
+      if (other.newName != null)
+        return false;
+    } else if (!this.newName.equals(other.newName))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.newName== null) ? 0 : this.newName.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ResolveTypeHierarchyItemParams.java b/java/org/eclipse/lsp4j/ResolveTypeHierarchyItemParams.java
new file mode 100644
index 0000000..6502735
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ResolveTypeHierarchyItemParams.java
@@ -0,0 +1,147 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import com.google.common.annotations.Beta;
+import org.eclipse.lsp4j.TypeHierarchyDirection;
+import org.eclipse.lsp4j.TypeHierarchyItem;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Request to resolve an unresolved {@link TypeHierarchyItem type hierarchy item} which is indicated if the
+ * {@link TypeHierarchyItem#getParents parents} or the {@link TypeHierarchyItem#getChildren children} is not
+ * defined. If resolved and no {@code parents} or {@code children} are available then an empty list is returned.
+ */
+@Beta
+@SuppressWarnings("all")
+public class ResolveTypeHierarchyItemParams {
+  /**
+   * The hierarchy item to resolve.
+   */
+  @NonNull
+  private TypeHierarchyItem item;
+  
+  /**
+   * The number of hierarchy levels to resolve. {@code 0} indicates no hierarchy level.
+   */
+  private int resolve;
+  
+  /**
+   * The direction of the type hierarchy resolution.
+   */
+  @NonNull
+  private TypeHierarchyDirection direction;
+  
+  public ResolveTypeHierarchyItemParams() {
+  }
+  
+  public ResolveTypeHierarchyItemParams(@NonNull final TypeHierarchyItem item, final int resolve, @NonNull final TypeHierarchyDirection direction) {
+    this.item = Preconditions.<TypeHierarchyItem>checkNotNull(item, "item");
+    this.resolve = resolve;
+    this.direction = Preconditions.<TypeHierarchyDirection>checkNotNull(direction, "direction");
+  }
+  
+  /**
+   * The hierarchy item to resolve.
+   */
+  @Pure
+  @NonNull
+  public TypeHierarchyItem getItem() {
+    return this.item;
+  }
+  
+  /**
+   * The hierarchy item to resolve.
+   */
+  public void setItem(@NonNull final TypeHierarchyItem item) {
+    this.item = Preconditions.checkNotNull(item, "item");
+  }
+  
+  /**
+   * The number of hierarchy levels to resolve. {@code 0} indicates no hierarchy level.
+   */
+  @Pure
+  public int getResolve() {
+    return this.resolve;
+  }
+  
+  /**
+   * The number of hierarchy levels to resolve. {@code 0} indicates no hierarchy level.
+   */
+  public void setResolve(final int resolve) {
+    this.resolve = resolve;
+  }
+  
+  /**
+   * The direction of the type hierarchy resolution.
+   */
+  @Pure
+  @NonNull
+  public TypeHierarchyDirection getDirection() {
+    return this.direction;
+  }
+  
+  /**
+   * The direction of the type hierarchy resolution.
+   */
+  public void setDirection(@NonNull final TypeHierarchyDirection direction) {
+    this.direction = Preconditions.checkNotNull(direction, "direction");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("item", this.item);
+    b.add("resolve", this.resolve);
+    b.add("direction", this.direction);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ResolveTypeHierarchyItemParams other = (ResolveTypeHierarchyItemParams) obj;
+    if (this.item == null) {
+      if (other.item != null)
+        return false;
+    } else if (!this.item.equals(other.item))
+      return false;
+    if (other.resolve != this.resolve)
+      return false;
+    if (this.direction == null) {
+      if (other.direction != null)
+        return false;
+    } else if (!this.direction.equals(other.direction))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.item== null) ? 0 : this.item.hashCode());
+    result = prime * result + this.resolve;
+    return prime * result + ((this.direction== null) ? 0 : this.direction.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ResourceChange.java b/java/org/eclipse/lsp4j/ResourceChange.java
new file mode 100644
index 0000000..3cc38fa
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ResourceChange.java
@@ -0,0 +1,127 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import com.google.common.annotations.Beta;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A resource change.
+ * <p><ul>
+ * <li>If both current and newUri has valid values this is considered to be a move operation.
+ * <li>If current has a valid value while newUri is null it is treated as a delete operation.
+ * <li>If current is null and newUri has a valid value a create operation is executed.
+ * </ul>
+ * 
+ * @deprecated As LSP introduces resource operation, use the {@link ResourceOperation} instead.
+ */
+@Beta
+@Deprecated
+@SuppressWarnings("all")
+public class ResourceChange {
+  /**
+   * The Uri for current resource. Required for delete and move operations
+   * otherwise it is null.
+   */
+  private String current;
+  
+  /**
+   * The new uri for the resource. Required for create and move operations.
+   * otherwise null.
+   * <p>
+   * Must be compatible with the current uri ie. must be a file
+   * uri if current is not null and is a file uri.
+   */
+  private String newUri;
+  
+  /**
+   * The Uri for current resource. Required for delete and move operations
+   * otherwise it is null.
+   */
+  @Pure
+  public String getCurrent() {
+    return this.current;
+  }
+  
+  /**
+   * The Uri for current resource. Required for delete and move operations
+   * otherwise it is null.
+   */
+  public void setCurrent(final String current) {
+    this.current = current;
+  }
+  
+  /**
+   * The new uri for the resource. Required for create and move operations.
+   * otherwise null.
+   * <p>
+   * Must be compatible with the current uri ie. must be a file
+   * uri if current is not null and is a file uri.
+   */
+  @Pure
+  public String getNewUri() {
+    return this.newUri;
+  }
+  
+  /**
+   * The new uri for the resource. Required for create and move operations.
+   * otherwise null.
+   * <p>
+   * Must be compatible with the current uri ie. must be a file
+   * uri if current is not null and is a file uri.
+   */
+  public void setNewUri(final String newUri) {
+    this.newUri = newUri;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("current", this.current);
+    b.add("newUri", this.newUri);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ResourceChange other = (ResourceChange) obj;
+    if (this.current == null) {
+      if (other.current != null)
+        return false;
+    } else if (!this.current.equals(other.current))
+      return false;
+    if (this.newUri == null) {
+      if (other.newUri != null)
+        return false;
+    } else if (!this.newUri.equals(other.newUri))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.current== null) ? 0 : this.current.hashCode());
+    return prime * result + ((this.newUri== null) ? 0 : this.newUri.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ResourceOperation.java b/java/org/eclipse/lsp4j/ResourceOperation.java
new file mode 100644
index 0000000..b33d1ed
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ResourceOperation.java
@@ -0,0 +1,119 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import com.google.gson.annotations.JsonAdapter;
+import org.eclipse.lsp4j.adapters.ResourceOperationTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@JsonAdapter(ResourceOperationTypeAdapter.class)
+@SuppressWarnings("all")
+public abstract class ResourceOperation {
+  /**
+   * The kind of resource operation. For allowed values, see {@link ResourceOperationKind}
+   */
+  @NonNull
+  private String kind;
+  
+  /**
+   * An optional annotation identifer describing the operation.
+   * <p>
+   * Since 3.16.0
+   */
+  private String annotationId;
+  
+  public ResourceOperation() {
+  }
+  
+  public ResourceOperation(@NonNull final String kind) {
+    this.kind = Preconditions.<String>checkNotNull(kind, "kind");
+  }
+  
+  /**
+   * The kind of resource operation. For allowed values, see {@link ResourceOperationKind}
+   */
+  @Pure
+  @NonNull
+  public String getKind() {
+    return this.kind;
+  }
+  
+  /**
+   * The kind of resource operation. For allowed values, see {@link ResourceOperationKind}
+   */
+  public void setKind(@NonNull final String kind) {
+    this.kind = Preconditions.checkNotNull(kind, "kind");
+  }
+  
+  /**
+   * An optional annotation identifer describing the operation.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public String getAnnotationId() {
+    return this.annotationId;
+  }
+  
+  /**
+   * An optional annotation identifer describing the operation.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setAnnotationId(final String annotationId) {
+    this.annotationId = annotationId;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("kind", this.kind);
+    b.add("annotationId", this.annotationId);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ResourceOperation other = (ResourceOperation) obj;
+    if (this.kind == null) {
+      if (other.kind != null)
+        return false;
+    } else if (!this.kind.equals(other.kind))
+      return false;
+    if (this.annotationId == null) {
+      if (other.annotationId != null)
+        return false;
+    } else if (!this.annotationId.equals(other.annotationId))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.kind== null) ? 0 : this.kind.hashCode());
+    return prime * result + ((this.annotationId== null) ? 0 : this.annotationId.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ResourceOperationKind.java b/java/org/eclipse/lsp4j/ResourceOperationKind.java
new file mode 100644
index 0000000..7de57ed
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ResourceOperationKind.java
@@ -0,0 +1,37 @@
+/******************************************************************************
+ * Copyright (c) 2018 Microsoft Corporation and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+
+package org.eclipse.lsp4j;
+
+/**
+ * The kind of resource operations supported by the client.
+ */
+public final class ResourceOperationKind {
+
+	private ResourceOperationKind() {
+	}
+
+	/**
+	 * Supports creating new files and folders.
+	 */
+	public static final String Create = "create";
+
+	/**
+	 * Supports renaming existing files and folders.
+	 */
+	public static final String Rename = "rename";
+
+	/**
+	 * Supports deleting existing files and folders.
+	 */
+	public static final String Delete = "delete";
+}
diff --git a/java/org/eclipse/lsp4j/ResponseErrorCode.java b/java/org/eclipse/lsp4j/ResponseErrorCode.java
new file mode 100644
index 0000000..047fd1e
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ResponseErrorCode.java
@@ -0,0 +1,46 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j;
+
+/**
+ * A number indicating the error type that occured.
+ * 
+ * @deprecated Use {@link org.eclipse.lsp4j.jsonrpc.messages.ResponseErrorCode} instead
+ */
+@Deprecated
+public enum ResponseErrorCode {
+	
+	ParseError(-32700),
+	
+	InvalidRequest(-32600),
+	
+	MethodNotFound(-32601),
+	
+	InvalidParams(-32602),
+	
+	InternalError(-32603),
+	
+	serverErrorStart(-32099),
+	
+	serverErrorEnd(-32000);
+	
+	private final int value;
+	
+	ResponseErrorCode(int value) {
+		this.value = value;
+	}
+	
+	public int getValue() {
+		return value;
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/SaveOptions.java b/java/org/eclipse/lsp4j/SaveOptions.java
new file mode 100644
index 0000000..3f58995
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SaveOptions.java
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Save options.
+ */
+@SuppressWarnings("all")
+public class SaveOptions {
+  /**
+   * The client is supposed to include the content on save.
+   */
+  private Boolean includeText;
+  
+  public SaveOptions() {
+  }
+  
+  public SaveOptions(final Boolean includeText) {
+    this.includeText = includeText;
+  }
+  
+  /**
+   * The client is supposed to include the content on save.
+   */
+  @Pure
+  public Boolean getIncludeText() {
+    return this.includeText;
+  }
+  
+  /**
+   * The client is supposed to include the content on save.
+   */
+  public void setIncludeText(final Boolean includeText) {
+    this.includeText = includeText;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("includeText", this.includeText);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SaveOptions other = (SaveOptions) obj;
+    if (this.includeText == null) {
+      if (other.includeText != null)
+        return false;
+    } else if (!this.includeText.equals(other.includeText))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.includeText== null) ? 0 : this.includeText.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SelectionRange.java b/java/org/eclipse/lsp4j/SelectionRange.java
new file mode 100644
index 0000000..784b161
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SelectionRange.java
@@ -0,0 +1,118 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A selection range represents a part of a selection hierarchy. A selection range
+ * may have a parent selection range that contains it.
+ * <p>
+ * Since 3.15.0
+ */
+@SuppressWarnings("all")
+public class SelectionRange {
+  /**
+   * The range of this selection range.
+   */
+  @NonNull
+  private Range range;
+  
+  /**
+   * The parent selection range containing this range. Therefore `parent.range` must contain {@link #range}.
+   */
+  private SelectionRange parent;
+  
+  public SelectionRange() {
+  }
+  
+  public SelectionRange(@NonNull final Range range, final SelectionRange parent) {
+    this.range = Preconditions.<Range>checkNotNull(range, "range");
+    this.parent = parent;
+  }
+  
+  /**
+   * The range of this selection range.
+   */
+  @Pure
+  @NonNull
+  public Range getRange() {
+    return this.range;
+  }
+  
+  /**
+   * The range of this selection range.
+   */
+  public void setRange(@NonNull final Range range) {
+    this.range = Preconditions.checkNotNull(range, "range");
+  }
+  
+  /**
+   * The parent selection range containing this range. Therefore `parent.range` must contain {@link #range}.
+   */
+  @Pure
+  public SelectionRange getParent() {
+    return this.parent;
+  }
+  
+  /**
+   * The parent selection range containing this range. Therefore `parent.range` must contain {@link #range}.
+   */
+  public void setParent(final SelectionRange parent) {
+    this.parent = parent;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("range", this.range);
+    b.add("parent", this.parent);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SelectionRange other = (SelectionRange) obj;
+    if (this.range == null) {
+      if (other.range != null)
+        return false;
+    } else if (!this.range.equals(other.range))
+      return false;
+    if (this.parent == null) {
+      if (other.parent != null)
+        return false;
+    } else if (!this.parent.equals(other.parent))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.range== null) ? 0 : this.range.hashCode());
+    return prime * result + ((this.parent== null) ? 0 : this.parent.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SelectionRangeCapabilities.java b/java/org/eclipse/lsp4j/SelectionRangeCapabilities.java
new file mode 100644
index 0000000..4f737c5
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SelectionRangeCapabilities.java
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to `textDocument/selectionRange` requests
+ * <p>
+ * Since 3.15.0
+ */
+@SuppressWarnings("all")
+public class SelectionRangeCapabilities extends DynamicRegistrationCapabilities {
+  public SelectionRangeCapabilities() {
+  }
+  
+  public SelectionRangeCapabilities(final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SelectionRangeOptions.java b/java/org/eclipse/lsp4j/SelectionRangeOptions.java
new file mode 100644
index 0000000..083aab0
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SelectionRangeOptions.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Selection range options.
+ * <p>
+ * Since 3.15.0
+ */
+@SuppressWarnings("all")
+public class SelectionRangeOptions extends AbstractWorkDoneProgressOptions {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SelectionRangeParams.java b/java/org/eclipse/lsp4j/SelectionRangeParams.java
new file mode 100644
index 0000000..ca95621
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SelectionRangeParams.java
@@ -0,0 +1,126 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.Position;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.WorkDoneProgressAndPartialResultParams;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A parameter literal used in selection range requests.
+ * <p>
+ * Since 3.15.0
+ */
+@SuppressWarnings("all")
+public class SelectionRangeParams extends WorkDoneProgressAndPartialResultParams {
+  /**
+   * The text document.
+   */
+  @NonNull
+  private TextDocumentIdentifier textDocument;
+  
+  /**
+   * The positions inside the text document.
+   */
+  @NonNull
+  private List<Position> positions;
+  
+  public SelectionRangeParams() {
+  }
+  
+  public SelectionRangeParams(@NonNull final TextDocumentIdentifier textDocument, @NonNull final List<Position> positions) {
+    this.textDocument = Preconditions.<TextDocumentIdentifier>checkNotNull(textDocument, "textDocument");
+    this.positions = Preconditions.<List<Position>>checkNotNull(positions, "positions");
+  }
+  
+  /**
+   * The text document.
+   */
+  @Pure
+  @NonNull
+  public TextDocumentIdentifier getTextDocument() {
+    return this.textDocument;
+  }
+  
+  /**
+   * The text document.
+   */
+  public void setTextDocument(@NonNull final TextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.checkNotNull(textDocument, "textDocument");
+  }
+  
+  /**
+   * The positions inside the text document.
+   */
+  @Pure
+  @NonNull
+  public List<Position> getPositions() {
+    return this.positions;
+  }
+  
+  /**
+   * The positions inside the text document.
+   */
+  public void setPositions(@NonNull final List<Position> positions) {
+    this.positions = Preconditions.checkNotNull(positions, "positions");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("textDocument", this.textDocument);
+    b.add("positions", this.positions);
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("partialResultToken", getPartialResultToken());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    SelectionRangeParams other = (SelectionRangeParams) obj;
+    if (this.textDocument == null) {
+      if (other.textDocument != null)
+        return false;
+    } else if (!this.textDocument.equals(other.textDocument))
+      return false;
+    if (this.positions == null) {
+      if (other.positions != null)
+        return false;
+    } else if (!this.positions.equals(other.positions))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.textDocument== null) ? 0 : this.textDocument.hashCode());
+    return prime * result + ((this.positions== null) ? 0 : this.positions.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SelectionRangeRegistrationOptions.java b/java/org/eclipse/lsp4j/SelectionRangeRegistrationOptions.java
new file mode 100644
index 0000000..aa3bdb1
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SelectionRangeRegistrationOptions.java
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractTextDocumentRegistrationAndWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Selection range registration options.
+ * <p>
+ * Since 3.15.0
+ */
+@SuppressWarnings("all")
+public class SelectionRangeRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  private String id;
+  
+  public SelectionRangeRegistrationOptions() {
+  }
+  
+  public SelectionRangeRegistrationOptions(final String id) {
+    this.id = id;
+  }
+  
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  @Pure
+  public String getId() {
+    return this.id;
+  }
+  
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  public void setId(final String id) {
+    this.id = id;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("id", this.id);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    SelectionRangeRegistrationOptions other = (SelectionRangeRegistrationOptions) obj;
+    if (this.id == null) {
+      if (other.id != null)
+        return false;
+    } else if (!this.id.equals(other.id))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.id== null) ? 0 : this.id.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SemanticTokenModifiers.java b/java/org/eclipse/lsp4j/SemanticTokenModifiers.java
new file mode 100644
index 0000000..a920c55
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SemanticTokenModifiers.java
@@ -0,0 +1,41 @@
+/**
+ * Copyright (c) 2020 Eric Dallo.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+/**
+ * Since 3.16.0
+ */
+public final class SemanticTokenModifiers {
+    private SemanticTokenModifiers() {
+    }
+
+    public static final String Declaration = "declaration";
+
+    public static final String Definition = "definition";
+
+    public static final String Readonly = "readonly";
+
+    public static final String Static = "static";
+
+    public static final String Deprecated = "deprecated";
+
+    public static final String Abstract = "abstract";
+
+    public static final String Async = "async";
+
+    public static final String Modification = "modification";
+
+    public static final String Documentation = "documentation";
+
+    public static final String DefaultLibrary = "defaultLibrary";
+
+}
diff --git a/java/org/eclipse/lsp4j/SemanticTokenTypes.java b/java/org/eclipse/lsp4j/SemanticTokenTypes.java
new file mode 100644
index 0000000..5abf16a
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SemanticTokenTypes.java
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2020 Eric Dallo.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+/**
+ * Since 3.16.0
+ */
+public final class SemanticTokenTypes {
+    private SemanticTokenTypes() {
+    }
+
+    public static final String Namespace = "namespace";
+
+    /**
+     * Represents a generic type. Acts as a fallback for types which
+     * can't be mapped to a specific type like class or enum.
+     */
+    public static final String Type = "type";
+
+    public static final String Class = "class";
+
+    public static final String Enum = "enum";
+
+    public static final String Interface = "interface";
+
+    public static final String Struct = "struct";
+
+    public static final String TypeParameter = "typeParameter";
+
+    public static final String Parameter = "parameter";
+
+    public static final String Variable = "variable";
+
+    public static final String Property = "property";
+
+    public static final String EnumMember = "enumMember";
+
+    public static final String Event = "event";
+
+    public static final String Function = "function";
+
+    /**
+     * @deprecated This was erroneously named prior to finalization. Use {@link #Method} instead.
+     */
+    @Deprecated
+    public static final String Member = "member";
+
+    public static final String Method = "method";
+
+    public static final String Macro = "macro";
+
+    public static final String Keyword = "keyword";
+
+    public static final String Modifier = "modifier";
+
+    public static final String Comment = "comment";
+
+    public static final String String = "string";
+
+    public static final String Number = "number";
+
+    public static final String Regexp = "regexp";
+
+    public static final String Operator = "operator";
+
+}
diff --git a/java/org/eclipse/lsp4j/SemanticTokens.java b/java/org/eclipse/lsp4j/SemanticTokens.java
new file mode 100644
index 0000000..f0cf906
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SemanticTokens.java
@@ -0,0 +1,125 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class SemanticTokens {
+  /**
+   * An optional result id. If provided and clients support delta updating
+   * the client will include the result id in the next semantic token request.
+   * A server can then instead of computing all semantic tokens again simply
+   * send a delta.
+   */
+  private String resultId;
+  
+  /**
+   * The actual tokens.
+   */
+  @NonNull
+  private List<Integer> data;
+  
+  public SemanticTokens(@NonNull final List<Integer> data) {
+    this.data = Preconditions.<List<Integer>>checkNotNull(data, "data");
+  }
+  
+  public SemanticTokens(final String resultId, @NonNull final List<Integer> data) {
+    this(data);
+    this.resultId = resultId;
+  }
+  
+  /**
+   * An optional result id. If provided and clients support delta updating
+   * the client will include the result id in the next semantic token request.
+   * A server can then instead of computing all semantic tokens again simply
+   * send a delta.
+   */
+  @Pure
+  public String getResultId() {
+    return this.resultId;
+  }
+  
+  /**
+   * An optional result id. If provided and clients support delta updating
+   * the client will include the result id in the next semantic token request.
+   * A server can then instead of computing all semantic tokens again simply
+   * send a delta.
+   */
+  public void setResultId(final String resultId) {
+    this.resultId = resultId;
+  }
+  
+  /**
+   * The actual tokens.
+   */
+  @Pure
+  @NonNull
+  public List<Integer> getData() {
+    return this.data;
+  }
+  
+  /**
+   * The actual tokens.
+   */
+  public void setData(@NonNull final List<Integer> data) {
+    this.data = Preconditions.checkNotNull(data, "data");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("resultId", this.resultId);
+    b.add("data", this.data);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SemanticTokens other = (SemanticTokens) obj;
+    if (this.resultId == null) {
+      if (other.resultId != null)
+        return false;
+    } else if (!this.resultId.equals(other.resultId))
+      return false;
+    if (this.data == null) {
+      if (other.data != null)
+        return false;
+    } else if (!this.data.equals(other.data))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.resultId== null) ? 0 : this.resultId.hashCode());
+    return prime * result + ((this.data== null) ? 0 : this.data.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SemanticTokensCapabilities.java b/java/org/eclipse/lsp4j/SemanticTokensCapabilities.java
new file mode 100644
index 0000000..3b2dabe
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SemanticTokensCapabilities.java
@@ -0,0 +1,263 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.lsp4j.SemanticTokensClientCapabilitiesRequests;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class SemanticTokensCapabilities extends DynamicRegistrationCapabilities {
+  /**
+   * Which requests the client supports and might send to the server.
+   */
+  @NonNull
+  private SemanticTokensClientCapabilitiesRequests requests;
+  
+  /**
+   * The token types that the client supports.
+   */
+  @NonNull
+  private List<String> tokenTypes;
+  
+  /**
+   * The token modifiers that the client supports.
+   */
+  @NonNull
+  private List<String> tokenModifiers;
+  
+  /**
+   * The formats the client supports.
+   * <p>
+   * See {@link TokenFormat} for allowed values.
+   */
+  @NonNull
+  private List<String> formats;
+  
+  /**
+   * Whether the client supports tokens that can overlap each other.
+   * <p>
+   * Since 3.16.0
+   */
+  private Boolean overlappingTokenSupport;
+  
+  /**
+   * Whether the client supports tokens that can span multiple lines.
+   * <p>
+   * Since 3.16.0
+   */
+  private Boolean multilineTokenSupport;
+  
+  public SemanticTokensCapabilities(final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+  }
+  
+  public SemanticTokensCapabilities(@NonNull final SemanticTokensClientCapabilitiesRequests requests, @NonNull final List<String> tokenTypes, @NonNull final List<String> tokenModifiers, @NonNull final List<String> formats) {
+    this.requests = Preconditions.<SemanticTokensClientCapabilitiesRequests>checkNotNull(requests, "requests");
+    this.tokenTypes = Preconditions.<List<String>>checkNotNull(tokenTypes, "tokenTypes");
+    this.tokenModifiers = Preconditions.<List<String>>checkNotNull(tokenModifiers, "tokenModifiers");
+    this.formats = Preconditions.<List<String>>checkNotNull(formats, "formats");
+  }
+  
+  public SemanticTokensCapabilities(final Boolean dynamicRegistration, @NonNull final SemanticTokensClientCapabilitiesRequests requests, @NonNull final List<String> tokenTypes, @NonNull final List<String> tokenModifiers, @NonNull final List<String> formats) {
+    super(dynamicRegistration);
+    this.requests = Preconditions.<SemanticTokensClientCapabilitiesRequests>checkNotNull(requests, "requests");
+    this.tokenTypes = Preconditions.<List<String>>checkNotNull(tokenTypes, "tokenTypes");
+    this.tokenModifiers = Preconditions.<List<String>>checkNotNull(tokenModifiers, "tokenModifiers");
+    this.formats = Preconditions.<List<String>>checkNotNull(formats, "formats");
+  }
+  
+  /**
+   * Which requests the client supports and might send to the server.
+   */
+  @Pure
+  @NonNull
+  public SemanticTokensClientCapabilitiesRequests getRequests() {
+    return this.requests;
+  }
+  
+  /**
+   * Which requests the client supports and might send to the server.
+   */
+  public void setRequests(@NonNull final SemanticTokensClientCapabilitiesRequests requests) {
+    this.requests = Preconditions.checkNotNull(requests, "requests");
+  }
+  
+  /**
+   * The token types that the client supports.
+   */
+  @Pure
+  @NonNull
+  public List<String> getTokenTypes() {
+    return this.tokenTypes;
+  }
+  
+  /**
+   * The token types that the client supports.
+   */
+  public void setTokenTypes(@NonNull final List<String> tokenTypes) {
+    this.tokenTypes = Preconditions.checkNotNull(tokenTypes, "tokenTypes");
+  }
+  
+  /**
+   * The token modifiers that the client supports.
+   */
+  @Pure
+  @NonNull
+  public List<String> getTokenModifiers() {
+    return this.tokenModifiers;
+  }
+  
+  /**
+   * The token modifiers that the client supports.
+   */
+  public void setTokenModifiers(@NonNull final List<String> tokenModifiers) {
+    this.tokenModifiers = Preconditions.checkNotNull(tokenModifiers, "tokenModifiers");
+  }
+  
+  /**
+   * The formats the client supports.
+   * <p>
+   * See {@link TokenFormat} for allowed values.
+   */
+  @Pure
+  @NonNull
+  public List<String> getFormats() {
+    return this.formats;
+  }
+  
+  /**
+   * The formats the client supports.
+   * <p>
+   * See {@link TokenFormat} for allowed values.
+   */
+  public void setFormats(@NonNull final List<String> formats) {
+    this.formats = Preconditions.checkNotNull(formats, "formats");
+  }
+  
+  /**
+   * Whether the client supports tokens that can overlap each other.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public Boolean getOverlappingTokenSupport() {
+    return this.overlappingTokenSupport;
+  }
+  
+  /**
+   * Whether the client supports tokens that can overlap each other.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setOverlappingTokenSupport(final Boolean overlappingTokenSupport) {
+    this.overlappingTokenSupport = overlappingTokenSupport;
+  }
+  
+  /**
+   * Whether the client supports tokens that can span multiple lines.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public Boolean getMultilineTokenSupport() {
+    return this.multilineTokenSupport;
+  }
+  
+  /**
+   * Whether the client supports tokens that can span multiple lines.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setMultilineTokenSupport(final Boolean multilineTokenSupport) {
+    this.multilineTokenSupport = multilineTokenSupport;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("requests", this.requests);
+    b.add("tokenTypes", this.tokenTypes);
+    b.add("tokenModifiers", this.tokenModifiers);
+    b.add("formats", this.formats);
+    b.add("overlappingTokenSupport", this.overlappingTokenSupport);
+    b.add("multilineTokenSupport", this.multilineTokenSupport);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    SemanticTokensCapabilities other = (SemanticTokensCapabilities) obj;
+    if (this.requests == null) {
+      if (other.requests != null)
+        return false;
+    } else if (!this.requests.equals(other.requests))
+      return false;
+    if (this.tokenTypes == null) {
+      if (other.tokenTypes != null)
+        return false;
+    } else if (!this.tokenTypes.equals(other.tokenTypes))
+      return false;
+    if (this.tokenModifiers == null) {
+      if (other.tokenModifiers != null)
+        return false;
+    } else if (!this.tokenModifiers.equals(other.tokenModifiers))
+      return false;
+    if (this.formats == null) {
+      if (other.formats != null)
+        return false;
+    } else if (!this.formats.equals(other.formats))
+      return false;
+    if (this.overlappingTokenSupport == null) {
+      if (other.overlappingTokenSupport != null)
+        return false;
+    } else if (!this.overlappingTokenSupport.equals(other.overlappingTokenSupport))
+      return false;
+    if (this.multilineTokenSupport == null) {
+      if (other.multilineTokenSupport != null)
+        return false;
+    } else if (!this.multilineTokenSupport.equals(other.multilineTokenSupport))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.requests== null) ? 0 : this.requests.hashCode());
+    result = prime * result + ((this.tokenTypes== null) ? 0 : this.tokenTypes.hashCode());
+    result = prime * result + ((this.tokenModifiers== null) ? 0 : this.tokenModifiers.hashCode());
+    result = prime * result + ((this.formats== null) ? 0 : this.formats.hashCode());
+    result = prime * result + ((this.overlappingTokenSupport== null) ? 0 : this.overlappingTokenSupport.hashCode());
+    return prime * result + ((this.multilineTokenSupport== null) ? 0 : this.multilineTokenSupport.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SemanticTokensClientCapabilitiesRequests.java b/java/org/eclipse/lsp4j/SemanticTokensClientCapabilitiesRequests.java
new file mode 100644
index 0000000..394cf26
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SemanticTokensClientCapabilitiesRequests.java
@@ -0,0 +1,163 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.SemanticTokensClientCapabilitiesRequestsFull;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class SemanticTokensClientCapabilitiesRequests {
+  /**
+   * The client will send the `textDocument/semanticTokens/range` request if
+   * the server provides a corresponding handler.
+   */
+  private Either<Boolean, Object> range;
+  
+  /**
+   * The client will send the `textDocument/semanticTokens/full` request if
+   * the server provides a corresponding handler.
+   */
+  private Either<Boolean, SemanticTokensClientCapabilitiesRequestsFull> full;
+  
+  public SemanticTokensClientCapabilitiesRequests() {
+  }
+  
+  public SemanticTokensClientCapabilitiesRequests(final Boolean full) {
+    this.setFull(full);
+  }
+  
+  public SemanticTokensClientCapabilitiesRequests(final SemanticTokensClientCapabilitiesRequestsFull full) {
+    this.setFull(full);
+  }
+  
+  public SemanticTokensClientCapabilitiesRequests(final Boolean full, final Boolean range) {
+    this.setFull(full);
+    this.setRange(range);
+  }
+  
+  public SemanticTokensClientCapabilitiesRequests(final SemanticTokensClientCapabilitiesRequestsFull full, final Boolean range) {
+    this.setFull(full);
+    this.setRange(range);
+  }
+  
+  /**
+   * The client will send the `textDocument/semanticTokens/range` request if
+   * the server provides a corresponding handler.
+   */
+  @Pure
+  public Either<Boolean, Object> getRange() {
+    return this.range;
+  }
+  
+  /**
+   * The client will send the `textDocument/semanticTokens/range` request if
+   * the server provides a corresponding handler.
+   */
+  public void setRange(final Either<Boolean, Object> range) {
+    this.range = range;
+  }
+  
+  public void setRange(final Boolean range) {
+    if (range == null) {
+      this.range = null;
+      return;
+    }
+    this.range = Either.forLeft(range);
+  }
+  
+  public void setRange(final Object range) {
+    if (range == null) {
+      this.range = null;
+      return;
+    }
+    this.range = Either.forRight(range);
+  }
+  
+  /**
+   * The client will send the `textDocument/semanticTokens/full` request if
+   * the server provides a corresponding handler.
+   */
+  @Pure
+  public Either<Boolean, SemanticTokensClientCapabilitiesRequestsFull> getFull() {
+    return this.full;
+  }
+  
+  /**
+   * The client will send the `textDocument/semanticTokens/full` request if
+   * the server provides a corresponding handler.
+   */
+  public void setFull(final Either<Boolean, SemanticTokensClientCapabilitiesRequestsFull> full) {
+    this.full = full;
+  }
+  
+  public void setFull(final Boolean full) {
+    if (full == null) {
+      this.full = null;
+      return;
+    }
+    this.full = Either.forLeft(full);
+  }
+  
+  public void setFull(final SemanticTokensClientCapabilitiesRequestsFull full) {
+    if (full == null) {
+      this.full = null;
+      return;
+    }
+    this.full = Either.forRight(full);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("range", this.range);
+    b.add("full", this.full);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SemanticTokensClientCapabilitiesRequests other = (SemanticTokensClientCapabilitiesRequests) obj;
+    if (this.range == null) {
+      if (other.range != null)
+        return false;
+    } else if (!this.range.equals(other.range))
+      return false;
+    if (this.full == null) {
+      if (other.full != null)
+        return false;
+    } else if (!this.full.equals(other.full))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.range== null) ? 0 : this.range.hashCode());
+    return prime * result + ((this.full== null) ? 0 : this.full.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SemanticTokensClientCapabilitiesRequestsFull.java b/java/org/eclipse/lsp4j/SemanticTokensClientCapabilitiesRequestsFull.java
new file mode 100644
index 0000000..4e0ea19
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SemanticTokensClientCapabilitiesRequestsFull.java
@@ -0,0 +1,83 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class SemanticTokensClientCapabilitiesRequestsFull {
+  /**
+   * The client will send the `textDocument/semanticTokens/full/delta` request if
+   * the server provides a corresponding handler.
+   */
+  private Boolean delta;
+  
+  public SemanticTokensClientCapabilitiesRequestsFull() {
+  }
+  
+  public SemanticTokensClientCapabilitiesRequestsFull(final Boolean delta) {
+    this.delta = delta;
+  }
+  
+  /**
+   * The client will send the `textDocument/semanticTokens/full/delta` request if
+   * the server provides a corresponding handler.
+   */
+  @Pure
+  public Boolean getDelta() {
+    return this.delta;
+  }
+  
+  /**
+   * The client will send the `textDocument/semanticTokens/full/delta` request if
+   * the server provides a corresponding handler.
+   */
+  public void setDelta(final Boolean delta) {
+    this.delta = delta;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("delta", this.delta);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SemanticTokensClientCapabilitiesRequestsFull other = (SemanticTokensClientCapabilitiesRequestsFull) obj;
+    if (this.delta == null) {
+      if (other.delta != null)
+        return false;
+    } else if (!this.delta.equals(other.delta))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.delta== null) ? 0 : this.delta.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SemanticTokensDelta.java b/java/org/eclipse/lsp4j/SemanticTokensDelta.java
new file mode 100644
index 0000000..f6a588e
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SemanticTokensDelta.java
@@ -0,0 +1,108 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.SemanticTokensEdit;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class SemanticTokensDelta {
+  private String resultId;
+  
+  /**
+   * The semantic token edits to transform a previous result into a new result.
+   */
+  @NonNull
+  private List<SemanticTokensEdit> edits;
+  
+  public SemanticTokensDelta(@NonNull final List<SemanticTokensEdit> edits) {
+    this.edits = Preconditions.<List<SemanticTokensEdit>>checkNotNull(edits, "edits");
+  }
+  
+  public SemanticTokensDelta(@NonNull final List<SemanticTokensEdit> edits, final String resultId) {
+    this.edits = Preconditions.<List<SemanticTokensEdit>>checkNotNull(edits, "edits");
+    this.resultId = resultId;
+  }
+  
+  @Pure
+  public String getResultId() {
+    return this.resultId;
+  }
+  
+  public void setResultId(final String resultId) {
+    this.resultId = resultId;
+  }
+  
+  /**
+   * The semantic token edits to transform a previous result into a new result.
+   */
+  @Pure
+  @NonNull
+  public List<SemanticTokensEdit> getEdits() {
+    return this.edits;
+  }
+  
+  /**
+   * The semantic token edits to transform a previous result into a new result.
+   */
+  public void setEdits(@NonNull final List<SemanticTokensEdit> edits) {
+    this.edits = Preconditions.checkNotNull(edits, "edits");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("resultId", this.resultId);
+    b.add("edits", this.edits);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SemanticTokensDelta other = (SemanticTokensDelta) obj;
+    if (this.resultId == null) {
+      if (other.resultId != null)
+        return false;
+    } else if (!this.resultId.equals(other.resultId))
+      return false;
+    if (this.edits == null) {
+      if (other.edits != null)
+        return false;
+    } else if (!this.edits.equals(other.edits))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.resultId== null) ? 0 : this.resultId.hashCode());
+    return prime * result + ((this.edits== null) ? 0 : this.edits.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SemanticTokensDeltaParams.java b/java/org/eclipse/lsp4j/SemanticTokensDeltaParams.java
new file mode 100644
index 0000000..bb5e95a
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SemanticTokensDeltaParams.java
@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.WorkDoneProgressAndPartialResultParams;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The request is sent from the client to the server to resolve semantic token deltas for a given whole file.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class SemanticTokensDeltaParams extends WorkDoneProgressAndPartialResultParams {
+  /**
+   * The text document.
+   */
+  @NonNull
+  private TextDocumentIdentifier textDocument;
+  
+  /**
+   * The result id of a previous response. The result Id can either point to a full response
+   * or a delta response depending on what was received last.
+   */
+  @NonNull
+  private String previousResultId;
+  
+  public SemanticTokensDeltaParams(@NonNull final TextDocumentIdentifier textDocument, @NonNull final String previousResultId) {
+    this.textDocument = Preconditions.<TextDocumentIdentifier>checkNotNull(textDocument, "textDocument");
+    this.previousResultId = Preconditions.<String>checkNotNull(previousResultId, "previousResultId");
+  }
+  
+  /**
+   * The text document.
+   */
+  @Pure
+  @NonNull
+  public TextDocumentIdentifier getTextDocument() {
+    return this.textDocument;
+  }
+  
+  /**
+   * The text document.
+   */
+  public void setTextDocument(@NonNull final TextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.checkNotNull(textDocument, "textDocument");
+  }
+  
+  /**
+   * The result id of a previous response. The result Id can either point to a full response
+   * or a delta response depending on what was received last.
+   */
+  @Pure
+  @NonNull
+  public String getPreviousResultId() {
+    return this.previousResultId;
+  }
+  
+  /**
+   * The result id of a previous response. The result Id can either point to a full response
+   * or a delta response depending on what was received last.
+   */
+  public void setPreviousResultId(@NonNull final String previousResultId) {
+    this.previousResultId = Preconditions.checkNotNull(previousResultId, "previousResultId");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("textDocument", this.textDocument);
+    b.add("previousResultId", this.previousResultId);
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("partialResultToken", getPartialResultToken());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    SemanticTokensDeltaParams other = (SemanticTokensDeltaParams) obj;
+    if (this.textDocument == null) {
+      if (other.textDocument != null)
+        return false;
+    } else if (!this.textDocument.equals(other.textDocument))
+      return false;
+    if (this.previousResultId == null) {
+      if (other.previousResultId != null)
+        return false;
+    } else if (!this.previousResultId.equals(other.previousResultId))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.textDocument== null) ? 0 : this.textDocument.hashCode());
+    return prime * result + ((this.previousResultId== null) ? 0 : this.previousResultId.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SemanticTokensDeltaPartialResult.java b/java/org/eclipse/lsp4j/SemanticTokensDeltaPartialResult.java
new file mode 100644
index 0000000..cbe979e
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SemanticTokensDeltaPartialResult.java
@@ -0,0 +1,74 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.SemanticTokensEdit;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class SemanticTokensDeltaPartialResult {
+  @NonNull
+  private List<SemanticTokensEdit> edits;
+  
+  public SemanticTokensDeltaPartialResult(@NonNull final List<SemanticTokensEdit> edits) {
+    this.edits = Preconditions.<List<SemanticTokensEdit>>checkNotNull(edits, "edits");
+  }
+  
+  @Pure
+  @NonNull
+  public List<SemanticTokensEdit> getEdits() {
+    return this.edits;
+  }
+  
+  public void setEdits(@NonNull final List<SemanticTokensEdit> edits) {
+    this.edits = Preconditions.checkNotNull(edits, "edits");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("edits", this.edits);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SemanticTokensDeltaPartialResult other = (SemanticTokensDeltaPartialResult) obj;
+    if (this.edits == null) {
+      if (other.edits != null)
+        return false;
+    } else if (!this.edits.equals(other.edits))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.edits== null) ? 0 : this.edits.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SemanticTokensEdit.java b/java/org/eclipse/lsp4j/SemanticTokensEdit.java
new file mode 100644
index 0000000..81f08f0
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SemanticTokensEdit.java
@@ -0,0 +1,130 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class SemanticTokensEdit {
+  /**
+   * The start offset of the edit.
+   */
+  private int start;
+  
+  /**
+   * The count of elements to remove.
+   */
+  private int deleteCount;
+  
+  /**
+   * The elements to insert.
+   */
+  private List<Integer> data;
+  
+  public SemanticTokensEdit(final int start, final int deleteCount, final List<Integer> data) {
+    this.start = start;
+    this.deleteCount = deleteCount;
+    this.data = data;
+  }
+  
+  /**
+   * The start offset of the edit.
+   */
+  @Pure
+  public int getStart() {
+    return this.start;
+  }
+  
+  /**
+   * The start offset of the edit.
+   */
+  public void setStart(final int start) {
+    this.start = start;
+  }
+  
+  /**
+   * The count of elements to remove.
+   */
+  @Pure
+  public int getDeleteCount() {
+    return this.deleteCount;
+  }
+  
+  /**
+   * The count of elements to remove.
+   */
+  public void setDeleteCount(final int deleteCount) {
+    this.deleteCount = deleteCount;
+  }
+  
+  /**
+   * The elements to insert.
+   */
+  @Pure
+  public List<Integer> getData() {
+    return this.data;
+  }
+  
+  /**
+   * The elements to insert.
+   */
+  public void setData(final List<Integer> data) {
+    this.data = data;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("start", this.start);
+    b.add("deleteCount", this.deleteCount);
+    b.add("data", this.data);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SemanticTokensEdit other = (SemanticTokensEdit) obj;
+    if (other.start != this.start)
+      return false;
+    if (other.deleteCount != this.deleteCount)
+      return false;
+    if (this.data == null) {
+      if (other.data != null)
+        return false;
+    } else if (!this.data.equals(other.data))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + this.start;
+    result = prime * result + this.deleteCount;
+    return prime * result + ((this.data== null) ? 0 : this.data.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SemanticTokensLegend.java b/java/org/eclipse/lsp4j/SemanticTokensLegend.java
new file mode 100644
index 0000000..5d25399
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SemanticTokensLegend.java
@@ -0,0 +1,116 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The legend used by the server
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class SemanticTokensLegend {
+  /**
+   * The token types that the client supports.
+   */
+  @NonNull
+  private List<String> tokenTypes;
+  
+  /**
+   * The token modifiers that the client supports.
+   */
+  @NonNull
+  private List<String> tokenModifiers;
+  
+  public SemanticTokensLegend(@NonNull final List<String> tokenTypes, @NonNull final List<String> tokenModifiers) {
+    this.tokenTypes = Preconditions.<List<String>>checkNotNull(tokenTypes, "tokenTypes");
+    this.tokenModifiers = Preconditions.<List<String>>checkNotNull(tokenModifiers, "tokenModifiers");
+  }
+  
+  /**
+   * The token types that the client supports.
+   */
+  @Pure
+  @NonNull
+  public List<String> getTokenTypes() {
+    return this.tokenTypes;
+  }
+  
+  /**
+   * The token types that the client supports.
+   */
+  public void setTokenTypes(@NonNull final List<String> tokenTypes) {
+    this.tokenTypes = Preconditions.checkNotNull(tokenTypes, "tokenTypes");
+  }
+  
+  /**
+   * The token modifiers that the client supports.
+   */
+  @Pure
+  @NonNull
+  public List<String> getTokenModifiers() {
+    return this.tokenModifiers;
+  }
+  
+  /**
+   * The token modifiers that the client supports.
+   */
+  public void setTokenModifiers(@NonNull final List<String> tokenModifiers) {
+    this.tokenModifiers = Preconditions.checkNotNull(tokenModifiers, "tokenModifiers");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("tokenTypes", this.tokenTypes);
+    b.add("tokenModifiers", this.tokenModifiers);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SemanticTokensLegend other = (SemanticTokensLegend) obj;
+    if (this.tokenTypes == null) {
+      if (other.tokenTypes != null)
+        return false;
+    } else if (!this.tokenTypes.equals(other.tokenTypes))
+      return false;
+    if (this.tokenModifiers == null) {
+      if (other.tokenModifiers != null)
+        return false;
+    } else if (!this.tokenModifiers.equals(other.tokenModifiers))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.tokenTypes== null) ? 0 : this.tokenTypes.hashCode());
+    return prime * result + ((this.tokenModifiers== null) ? 0 : this.tokenModifiers.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SemanticTokensParams.java b/java/org/eclipse/lsp4j/SemanticTokensParams.java
new file mode 100644
index 0000000..5fd1311
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SemanticTokensParams.java
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.WorkDoneProgressAndPartialResultParams;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The request is sent from the client to the server to resolve semantic tokens for a given whole file.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class SemanticTokensParams extends WorkDoneProgressAndPartialResultParams {
+  /**
+   * The text document.
+   */
+  @NonNull
+  private TextDocumentIdentifier textDocument;
+  
+  public SemanticTokensParams(@NonNull final TextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.<TextDocumentIdentifier>checkNotNull(textDocument, "textDocument");
+  }
+  
+  /**
+   * The text document.
+   */
+  @Pure
+  @NonNull
+  public TextDocumentIdentifier getTextDocument() {
+    return this.textDocument;
+  }
+  
+  /**
+   * The text document.
+   */
+  public void setTextDocument(@NonNull final TextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.checkNotNull(textDocument, "textDocument");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("textDocument", this.textDocument);
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("partialResultToken", getPartialResultToken());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    SemanticTokensParams other = (SemanticTokensParams) obj;
+    if (this.textDocument == null) {
+      if (other.textDocument != null)
+        return false;
+    } else if (!this.textDocument.equals(other.textDocument))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.textDocument== null) ? 0 : this.textDocument.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SemanticTokensPartialResult.java b/java/org/eclipse/lsp4j/SemanticTokensPartialResult.java
new file mode 100644
index 0000000..8141b81
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SemanticTokensPartialResult.java
@@ -0,0 +1,73 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class SemanticTokensPartialResult {
+  @NonNull
+  private List<Integer> data;
+  
+  public SemanticTokensPartialResult(@NonNull final List<Integer> data) {
+    this.data = Preconditions.<List<Integer>>checkNotNull(data, "data");
+  }
+  
+  @Pure
+  @NonNull
+  public List<Integer> getData() {
+    return this.data;
+  }
+  
+  public void setData(@NonNull final List<Integer> data) {
+    this.data = Preconditions.checkNotNull(data, "data");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("data", this.data);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SemanticTokensPartialResult other = (SemanticTokensPartialResult) obj;
+    if (this.data == null) {
+      if (other.data != null)
+        return false;
+    } else if (!this.data.equals(other.data))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.data== null) ? 0 : this.data.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SemanticTokensRangeParams.java b/java/org/eclipse/lsp4j/SemanticTokensRangeParams.java
new file mode 100644
index 0000000..d73b02a
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SemanticTokensRangeParams.java
@@ -0,0 +1,122 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.WorkDoneProgressAndPartialResultParams;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The request is sent from the client to the server to resolve semantic tokens for a range in a given file.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class SemanticTokensRangeParams extends WorkDoneProgressAndPartialResultParams {
+  /**
+   * The text document.
+   */
+  @NonNull
+  private TextDocumentIdentifier textDocument;
+  
+  /**
+   * The range the semantic tokens are requested for.
+   */
+  @NonNull
+  private Range range;
+  
+  public SemanticTokensRangeParams(@NonNull final TextDocumentIdentifier textDocument, @NonNull final Range range) {
+    this.textDocument = Preconditions.<TextDocumentIdentifier>checkNotNull(textDocument, "textDocument");
+    this.range = Preconditions.<Range>checkNotNull(range, "range");
+  }
+  
+  /**
+   * The text document.
+   */
+  @Pure
+  @NonNull
+  public TextDocumentIdentifier getTextDocument() {
+    return this.textDocument;
+  }
+  
+  /**
+   * The text document.
+   */
+  public void setTextDocument(@NonNull final TextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.checkNotNull(textDocument, "textDocument");
+  }
+  
+  /**
+   * The range the semantic tokens are requested for.
+   */
+  @Pure
+  @NonNull
+  public Range getRange() {
+    return this.range;
+  }
+  
+  /**
+   * The range the semantic tokens are requested for.
+   */
+  public void setRange(@NonNull final Range range) {
+    this.range = Preconditions.checkNotNull(range, "range");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("textDocument", this.textDocument);
+    b.add("range", this.range);
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("partialResultToken", getPartialResultToken());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    SemanticTokensRangeParams other = (SemanticTokensRangeParams) obj;
+    if (this.textDocument == null) {
+      if (other.textDocument != null)
+        return false;
+    } else if (!this.textDocument.equals(other.textDocument))
+      return false;
+    if (this.range == null) {
+      if (other.range != null)
+        return false;
+    } else if (!this.range.equals(other.range))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.textDocument== null) ? 0 : this.textDocument.hashCode());
+    return prime * result + ((this.range== null) ? 0 : this.range.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SemanticTokensServerFull.java b/java/org/eclipse/lsp4j/SemanticTokensServerFull.java
new file mode 100644
index 0000000..90dbb81
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SemanticTokensServerFull.java
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Server supports providing semantic tokens for a full document.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class SemanticTokensServerFull {
+  /**
+   * The server supports deltas for full documents.
+   */
+  private Boolean delta;
+  
+  public SemanticTokensServerFull() {
+  }
+  
+  public SemanticTokensServerFull(final Boolean delta) {
+    this.delta = delta;
+  }
+  
+  /**
+   * The server supports deltas for full documents.
+   */
+  @Pure
+  public Boolean getDelta() {
+    return this.delta;
+  }
+  
+  /**
+   * The server supports deltas for full documents.
+   */
+  public void setDelta(final Boolean delta) {
+    this.delta = delta;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("delta", this.delta);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SemanticTokensServerFull other = (SemanticTokensServerFull) obj;
+    if (this.delta == null) {
+      if (other.delta != null)
+        return false;
+    } else if (!this.delta.equals(other.delta))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.delta== null) ? 0 : this.delta.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SemanticTokensWithRegistrationOptions.java b/java/org/eclipse/lsp4j/SemanticTokensWithRegistrationOptions.java
new file mode 100644
index 0000000..3561113
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SemanticTokensWithRegistrationOptions.java
@@ -0,0 +1,273 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.AbstractWorkDoneProgressOptions;
+import org.eclipse.lsp4j.DocumentFilter;
+import org.eclipse.lsp4j.SemanticTokensLegend;
+import org.eclipse.lsp4j.SemanticTokensServerFull;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class SemanticTokensWithRegistrationOptions extends AbstractWorkDoneProgressOptions {
+  /**
+   * The legend used by the server
+   */
+  @NonNull
+  private SemanticTokensLegend legend;
+  
+  /**
+   * Server supports providing semantic tokens for a specific range
+   * of a document.
+   */
+  private Either<Boolean, Object> range;
+  
+  /**
+   * Server supports providing semantic tokens for a full document.
+   */
+  private Either<Boolean, SemanticTokensServerFull> full;
+  
+  /**
+   * A document selector to identify the scope of the registration. If set to null
+   * the document selector provided on the client side will be used.
+   */
+  private List<DocumentFilter> documentSelector;
+  
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  private String id;
+  
+  public SemanticTokensWithRegistrationOptions() {
+  }
+  
+  public SemanticTokensWithRegistrationOptions(@NonNull final SemanticTokensLegend legend) {
+    this.legend = Preconditions.<SemanticTokensLegend>checkNotNull(legend, "legend");
+  }
+  
+  public SemanticTokensWithRegistrationOptions(@NonNull final SemanticTokensLegend legend, final Boolean full) {
+    this(legend);
+    this.setFull(full);
+  }
+  
+  public SemanticTokensWithRegistrationOptions(@NonNull final SemanticTokensLegend legend, final SemanticTokensServerFull full) {
+    this(legend);
+    this.setFull(full);
+  }
+  
+  public SemanticTokensWithRegistrationOptions(@NonNull final SemanticTokensLegend legend, final Boolean full, final Boolean range) {
+    this(legend);
+    this.setFull(full);
+    this.setRange(range);
+  }
+  
+  public SemanticTokensWithRegistrationOptions(@NonNull final SemanticTokensLegend legend, final SemanticTokensServerFull full, final Boolean range) {
+    this(legend);
+    this.setFull(full);
+    this.setRange(range);
+  }
+  
+  public SemanticTokensWithRegistrationOptions(@NonNull final SemanticTokensLegend legend, final SemanticTokensServerFull full, final Boolean range, final List<DocumentFilter> documentSelector) {
+    this(legend);
+    this.setFull(full);
+    this.setRange(range);
+    this.documentSelector = documentSelector;
+  }
+  
+  /**
+   * The legend used by the server
+   */
+  @Pure
+  @NonNull
+  public SemanticTokensLegend getLegend() {
+    return this.legend;
+  }
+  
+  /**
+   * The legend used by the server
+   */
+  public void setLegend(@NonNull final SemanticTokensLegend legend) {
+    this.legend = Preconditions.checkNotNull(legend, "legend");
+  }
+  
+  /**
+   * Server supports providing semantic tokens for a specific range
+   * of a document.
+   */
+  @Pure
+  public Either<Boolean, Object> getRange() {
+    return this.range;
+  }
+  
+  /**
+   * Server supports providing semantic tokens for a specific range
+   * of a document.
+   */
+  public void setRange(final Either<Boolean, Object> range) {
+    this.range = range;
+  }
+  
+  public void setRange(final Boolean range) {
+    if (range == null) {
+      this.range = null;
+      return;
+    }
+    this.range = Either.forLeft(range);
+  }
+  
+  public void setRange(final Object range) {
+    if (range == null) {
+      this.range = null;
+      return;
+    }
+    this.range = Either.forRight(range);
+  }
+  
+  /**
+   * Server supports providing semantic tokens for a full document.
+   */
+  @Pure
+  public Either<Boolean, SemanticTokensServerFull> getFull() {
+    return this.full;
+  }
+  
+  /**
+   * Server supports providing semantic tokens for a full document.
+   */
+  public void setFull(final Either<Boolean, SemanticTokensServerFull> full) {
+    this.full = full;
+  }
+  
+  public void setFull(final Boolean full) {
+    if (full == null) {
+      this.full = null;
+      return;
+    }
+    this.full = Either.forLeft(full);
+  }
+  
+  public void setFull(final SemanticTokensServerFull full) {
+    if (full == null) {
+      this.full = null;
+      return;
+    }
+    this.full = Either.forRight(full);
+  }
+  
+  /**
+   * A document selector to identify the scope of the registration. If set to null
+   * the document selector provided on the client side will be used.
+   */
+  @Pure
+  public List<DocumentFilter> getDocumentSelector() {
+    return this.documentSelector;
+  }
+  
+  /**
+   * A document selector to identify the scope of the registration. If set to null
+   * the document selector provided on the client side will be used.
+   */
+  public void setDocumentSelector(final List<DocumentFilter> documentSelector) {
+    this.documentSelector = documentSelector;
+  }
+  
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  @Pure
+  public String getId() {
+    return this.id;
+  }
+  
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  public void setId(final String id) {
+    this.id = id;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("legend", this.legend);
+    b.add("range", this.range);
+    b.add("full", this.full);
+    b.add("documentSelector", this.documentSelector);
+    b.add("id", this.id);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    SemanticTokensWithRegistrationOptions other = (SemanticTokensWithRegistrationOptions) obj;
+    if (this.legend == null) {
+      if (other.legend != null)
+        return false;
+    } else if (!this.legend.equals(other.legend))
+      return false;
+    if (this.range == null) {
+      if (other.range != null)
+        return false;
+    } else if (!this.range.equals(other.range))
+      return false;
+    if (this.full == null) {
+      if (other.full != null)
+        return false;
+    } else if (!this.full.equals(other.full))
+      return false;
+    if (this.documentSelector == null) {
+      if (other.documentSelector != null)
+        return false;
+    } else if (!this.documentSelector.equals(other.documentSelector))
+      return false;
+    if (this.id == null) {
+      if (other.id != null)
+        return false;
+    } else if (!this.id.equals(other.id))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.legend== null) ? 0 : this.legend.hashCode());
+    result = prime * result + ((this.range== null) ? 0 : this.range.hashCode());
+    result = prime * result + ((this.full== null) ? 0 : this.full.hashCode());
+    result = prime * result + ((this.documentSelector== null) ? 0 : this.documentSelector.hashCode());
+    return prime * result + ((this.id== null) ? 0 : this.id.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SemanticTokensWorkspaceCapabilities.java b/java/org/eclipse/lsp4j/SemanticTokensWorkspaceCapabilities.java
new file mode 100644
index 0000000..da9067a
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SemanticTokensWorkspaceCapabilities.java
@@ -0,0 +1,101 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the semantic token requests scoped to the
+ * workspace.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class SemanticTokensWorkspaceCapabilities {
+  /**
+   * Whether the client implementation supports a refresh request sent from the
+   * server to the client.
+   * <p>
+   * Note that this event is global and will force the client to refresh all
+   * semantic tokens currently shown. It should be used with absolute care and is
+   * useful for situations where a server for example detects a project-wide
+   * change that requires such a calculation.
+   */
+  private Boolean refreshSupport;
+  
+  public SemanticTokensWorkspaceCapabilities() {
+  }
+  
+  public SemanticTokensWorkspaceCapabilities(final Boolean refreshSupport) {
+    this.refreshSupport = refreshSupport;
+  }
+  
+  /**
+   * Whether the client implementation supports a refresh request sent from the
+   * server to the client.
+   * <p>
+   * Note that this event is global and will force the client to refresh all
+   * semantic tokens currently shown. It should be used with absolute care and is
+   * useful for situations where a server for example detects a project-wide
+   * change that requires such a calculation.
+   */
+  @Pure
+  public Boolean getRefreshSupport() {
+    return this.refreshSupport;
+  }
+  
+  /**
+   * Whether the client implementation supports a refresh request sent from the
+   * server to the client.
+   * <p>
+   * Note that this event is global and will force the client to refresh all
+   * semantic tokens currently shown. It should be used with absolute care and is
+   * useful for situations where a server for example detects a project-wide
+   * change that requires such a calculation.
+   */
+  public void setRefreshSupport(final Boolean refreshSupport) {
+    this.refreshSupport = refreshSupport;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("refreshSupport", this.refreshSupport);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SemanticTokensWorkspaceCapabilities other = (SemanticTokensWorkspaceCapabilities) obj;
+    if (this.refreshSupport == null) {
+      if (other.refreshSupport != null)
+        return false;
+    } else if (!this.refreshSupport.equals(other.refreshSupport))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.refreshSupport== null) ? 0 : this.refreshSupport.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ServerCapabilities.java b/java/org/eclipse/lsp4j/ServerCapabilities.java
new file mode 100644
index 0000000..9a10954
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ServerCapabilities.java
@@ -0,0 +1,1317 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import com.google.common.annotations.Beta;
+import com.google.gson.annotations.JsonAdapter;
+import org.eclipse.lsp4j.CallHierarchyRegistrationOptions;
+import org.eclipse.lsp4j.CodeActionOptions;
+import org.eclipse.lsp4j.CodeLensOptions;
+import org.eclipse.lsp4j.ColorProviderOptions;
+import org.eclipse.lsp4j.CompletionOptions;
+import org.eclipse.lsp4j.DeclarationRegistrationOptions;
+import org.eclipse.lsp4j.DefinitionOptions;
+import org.eclipse.lsp4j.DocumentFormattingOptions;
+import org.eclipse.lsp4j.DocumentHighlightOptions;
+import org.eclipse.lsp4j.DocumentLinkOptions;
+import org.eclipse.lsp4j.DocumentOnTypeFormattingOptions;
+import org.eclipse.lsp4j.DocumentRangeFormattingOptions;
+import org.eclipse.lsp4j.DocumentSymbolOptions;
+import org.eclipse.lsp4j.ExecuteCommandOptions;
+import org.eclipse.lsp4j.FoldingRangeProviderOptions;
+import org.eclipse.lsp4j.HoverOptions;
+import org.eclipse.lsp4j.ImplementationRegistrationOptions;
+import org.eclipse.lsp4j.LinkedEditingRangeRegistrationOptions;
+import org.eclipse.lsp4j.MonikerRegistrationOptions;
+import org.eclipse.lsp4j.ReferenceOptions;
+import org.eclipse.lsp4j.RenameOptions;
+import org.eclipse.lsp4j.SelectionRangeRegistrationOptions;
+import org.eclipse.lsp4j.SemanticTokensWithRegistrationOptions;
+import org.eclipse.lsp4j.SignatureHelpOptions;
+import org.eclipse.lsp4j.StaticRegistrationOptions;
+import org.eclipse.lsp4j.TextDocumentSyncKind;
+import org.eclipse.lsp4j.TextDocumentSyncOptions;
+import org.eclipse.lsp4j.TypeDefinitionRegistrationOptions;
+import org.eclipse.lsp4j.WorkspaceServerCapabilities;
+import org.eclipse.lsp4j.WorkspaceSymbolOptions;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The server can signal these capabilities
+ */
+@SuppressWarnings("all")
+public class ServerCapabilities {
+  /**
+   * Defines how text documents are synced. Is either a detailed structure defining each notification or
+   * for backwards compatibility the TextDocumentSyncKind number. If omitted it defaults to
+   * {@link TextDocumentSyncKind#None}
+   */
+  private Either<TextDocumentSyncKind, TextDocumentSyncOptions> textDocumentSync;
+  
+  /**
+   * The server provides hover support.
+   */
+  private Either<Boolean, HoverOptions> hoverProvider;
+  
+  /**
+   * The server provides completion support.
+   */
+  private CompletionOptions completionProvider;
+  
+  /**
+   * The server provides signature help support.
+   */
+  private SignatureHelpOptions signatureHelpProvider;
+  
+  /**
+   * The server provides goto definition support.
+   */
+  private Either<Boolean, DefinitionOptions> definitionProvider;
+  
+  /**
+   * The server provides Goto Type Definition support.
+   * <p>
+   * Since 3.6.0
+   */
+  private Either<Boolean, TypeDefinitionRegistrationOptions> typeDefinitionProvider;
+  
+  /**
+   * The server provides Goto Implementation support.
+   * <p>
+   * Since 3.6.0
+   */
+  private Either<Boolean, ImplementationRegistrationOptions> implementationProvider;
+  
+  /**
+   * The server provides find references support.
+   */
+  private Either<Boolean, ReferenceOptions> referencesProvider;
+  
+  /**
+   * The server provides document highlight support.
+   */
+  private Either<Boolean, DocumentHighlightOptions> documentHighlightProvider;
+  
+  /**
+   * The server provides document symbol support.
+   */
+  private Either<Boolean, DocumentSymbolOptions> documentSymbolProvider;
+  
+  /**
+   * The server provides workspace symbol support.
+   */
+  private Either<Boolean, WorkspaceSymbolOptions> workspaceSymbolProvider;
+  
+  /**
+   * The server provides code actions. The {@link CodeActionOptions} return type is only
+   * valid if the client signals code action literal support via the property
+   * {@link CodeActionCapabilities#codeActionLiteralSupport}.
+   */
+  private Either<Boolean, CodeActionOptions> codeActionProvider;
+  
+  /**
+   * The server provides code lens.
+   */
+  private CodeLensOptions codeLensProvider;
+  
+  /**
+   * The server provides document formatting.
+   */
+  private Either<Boolean, DocumentFormattingOptions> documentFormattingProvider;
+  
+  /**
+   * The server provides document range formatting.
+   */
+  private Either<Boolean, DocumentRangeFormattingOptions> documentRangeFormattingProvider;
+  
+  /**
+   * The server provides document formatting on typing.
+   */
+  private DocumentOnTypeFormattingOptions documentOnTypeFormattingProvider;
+  
+  /**
+   * The server provides rename support.
+   */
+  private Either<Boolean, RenameOptions> renameProvider;
+  
+  /**
+   * The server provides document link support.
+   */
+  private DocumentLinkOptions documentLinkProvider;
+  
+  /**
+   * The server provides color provider support.
+   * <p>
+   * Since 3.6.0
+   */
+  private Either<Boolean, ColorProviderOptions> colorProvider;
+  
+  /**
+   * The server provides folding provider support.
+   * <p>
+   * Since 3.10.0
+   */
+  private Either<Boolean, FoldingRangeProviderOptions> foldingRangeProvider;
+  
+  /**
+   * The server provides go to declaration support.
+   * <p>
+   * Since 3.14.0
+   */
+  private Either<Boolean, DeclarationRegistrationOptions> declarationProvider;
+  
+  /**
+   * The server provides execute command support.
+   */
+  private ExecuteCommandOptions executeCommandProvider;
+  
+  /**
+   * Workspace specific server capabilities
+   */
+  private WorkspaceServerCapabilities workspace;
+  
+  /**
+   * Server capability for calculating super- and subtype hierarchies.
+   * The LS supports the type hierarchy language feature, if this capability is set to {@code true}.
+   * <p>
+   * <b>Note:</b> the <a href=
+   * "https://github.com/Microsoft/vscode-languageserver-node/pull/426">{@code textDocument/typeHierarchy}
+   * language feature</a> is not yet part of the official LSP specification.
+   */
+  @Beta
+  private Either<Boolean, StaticRegistrationOptions> typeHierarchyProvider;
+  
+  /**
+   * The server provides Call Hierarchy support.
+   * <p>
+   * Since 3.16.0
+   */
+  private Either<Boolean, CallHierarchyRegistrationOptions> callHierarchyProvider;
+  
+  /**
+   * The server provides selection range support.
+   * <p>
+   * Since 3.15.0
+   */
+  private Either<Boolean, SelectionRangeRegistrationOptions> selectionRangeProvider;
+  
+  /**
+   * The server provides linked editing range support.
+   * <p>
+   * Since 3.16.0
+   */
+  private Either<Boolean, LinkedEditingRangeRegistrationOptions> linkedEditingRangeProvider;
+  
+  /**
+   * The server provides semantic tokens support.
+   * <p>
+   * Since 3.16.0
+   */
+  private SemanticTokensWithRegistrationOptions semanticTokensProvider;
+  
+  /**
+   * Whether server provides moniker support.
+   * <p>
+   * Since 3.16.0
+   */
+  private Either<Boolean, MonikerRegistrationOptions> monikerProvider;
+  
+  /**
+   * Experimental server capabilities.
+   */
+  @JsonAdapter(JsonElementTypeAdapter.Factory.class)
+  private Object experimental;
+  
+  /**
+   * Defines how text documents are synced. Is either a detailed structure defining each notification or
+   * for backwards compatibility the TextDocumentSyncKind number. If omitted it defaults to
+   * {@link TextDocumentSyncKind#None}
+   */
+  @Pure
+  public Either<TextDocumentSyncKind, TextDocumentSyncOptions> getTextDocumentSync() {
+    return this.textDocumentSync;
+  }
+  
+  /**
+   * Defines how text documents are synced. Is either a detailed structure defining each notification or
+   * for backwards compatibility the TextDocumentSyncKind number. If omitted it defaults to
+   * {@link TextDocumentSyncKind#None}
+   */
+  public void setTextDocumentSync(final Either<TextDocumentSyncKind, TextDocumentSyncOptions> textDocumentSync) {
+    this.textDocumentSync = textDocumentSync;
+  }
+  
+  public void setTextDocumentSync(final TextDocumentSyncKind textDocumentSync) {
+    if (textDocumentSync == null) {
+      this.textDocumentSync = null;
+      return;
+    }
+    this.textDocumentSync = Either.forLeft(textDocumentSync);
+  }
+  
+  public void setTextDocumentSync(final TextDocumentSyncOptions textDocumentSync) {
+    if (textDocumentSync == null) {
+      this.textDocumentSync = null;
+      return;
+    }
+    this.textDocumentSync = Either.forRight(textDocumentSync);
+  }
+  
+  /**
+   * The server provides hover support.
+   */
+  @Pure
+  public Either<Boolean, HoverOptions> getHoverProvider() {
+    return this.hoverProvider;
+  }
+  
+  /**
+   * The server provides hover support.
+   */
+  public void setHoverProvider(final Either<Boolean, HoverOptions> hoverProvider) {
+    this.hoverProvider = hoverProvider;
+  }
+  
+  public void setHoverProvider(final Boolean hoverProvider) {
+    if (hoverProvider == null) {
+      this.hoverProvider = null;
+      return;
+    }
+    this.hoverProvider = Either.forLeft(hoverProvider);
+  }
+  
+  public void setHoverProvider(final HoverOptions hoverProvider) {
+    if (hoverProvider == null) {
+      this.hoverProvider = null;
+      return;
+    }
+    this.hoverProvider = Either.forRight(hoverProvider);
+  }
+  
+  /**
+   * The server provides completion support.
+   */
+  @Pure
+  public CompletionOptions getCompletionProvider() {
+    return this.completionProvider;
+  }
+  
+  /**
+   * The server provides completion support.
+   */
+  public void setCompletionProvider(final CompletionOptions completionProvider) {
+    this.completionProvider = completionProvider;
+  }
+  
+  /**
+   * The server provides signature help support.
+   */
+  @Pure
+  public SignatureHelpOptions getSignatureHelpProvider() {
+    return this.signatureHelpProvider;
+  }
+  
+  /**
+   * The server provides signature help support.
+   */
+  public void setSignatureHelpProvider(final SignatureHelpOptions signatureHelpProvider) {
+    this.signatureHelpProvider = signatureHelpProvider;
+  }
+  
+  /**
+   * The server provides goto definition support.
+   */
+  @Pure
+  public Either<Boolean, DefinitionOptions> getDefinitionProvider() {
+    return this.definitionProvider;
+  }
+  
+  /**
+   * The server provides goto definition support.
+   */
+  public void setDefinitionProvider(final Either<Boolean, DefinitionOptions> definitionProvider) {
+    this.definitionProvider = definitionProvider;
+  }
+  
+  public void setDefinitionProvider(final Boolean definitionProvider) {
+    if (definitionProvider == null) {
+      this.definitionProvider = null;
+      return;
+    }
+    this.definitionProvider = Either.forLeft(definitionProvider);
+  }
+  
+  public void setDefinitionProvider(final DefinitionOptions definitionProvider) {
+    if (definitionProvider == null) {
+      this.definitionProvider = null;
+      return;
+    }
+    this.definitionProvider = Either.forRight(definitionProvider);
+  }
+  
+  /**
+   * The server provides Goto Type Definition support.
+   * <p>
+   * Since 3.6.0
+   */
+  @Pure
+  public Either<Boolean, TypeDefinitionRegistrationOptions> getTypeDefinitionProvider() {
+    return this.typeDefinitionProvider;
+  }
+  
+  /**
+   * The server provides Goto Type Definition support.
+   * <p>
+   * Since 3.6.0
+   */
+  public void setTypeDefinitionProvider(final Either<Boolean, TypeDefinitionRegistrationOptions> typeDefinitionProvider) {
+    this.typeDefinitionProvider = typeDefinitionProvider;
+  }
+  
+  public void setTypeDefinitionProvider(final Boolean typeDefinitionProvider) {
+    if (typeDefinitionProvider == null) {
+      this.typeDefinitionProvider = null;
+      return;
+    }
+    this.typeDefinitionProvider = Either.forLeft(typeDefinitionProvider);
+  }
+  
+  public void setTypeDefinitionProvider(final TypeDefinitionRegistrationOptions typeDefinitionProvider) {
+    if (typeDefinitionProvider == null) {
+      this.typeDefinitionProvider = null;
+      return;
+    }
+    this.typeDefinitionProvider = Either.forRight(typeDefinitionProvider);
+  }
+  
+  /**
+   * The server provides Goto Implementation support.
+   * <p>
+   * Since 3.6.0
+   */
+  @Pure
+  public Either<Boolean, ImplementationRegistrationOptions> getImplementationProvider() {
+    return this.implementationProvider;
+  }
+  
+  /**
+   * The server provides Goto Implementation support.
+   * <p>
+   * Since 3.6.0
+   */
+  public void setImplementationProvider(final Either<Boolean, ImplementationRegistrationOptions> implementationProvider) {
+    this.implementationProvider = implementationProvider;
+  }
+  
+  public void setImplementationProvider(final Boolean implementationProvider) {
+    if (implementationProvider == null) {
+      this.implementationProvider = null;
+      return;
+    }
+    this.implementationProvider = Either.forLeft(implementationProvider);
+  }
+  
+  public void setImplementationProvider(final ImplementationRegistrationOptions implementationProvider) {
+    if (implementationProvider == null) {
+      this.implementationProvider = null;
+      return;
+    }
+    this.implementationProvider = Either.forRight(implementationProvider);
+  }
+  
+  /**
+   * The server provides find references support.
+   */
+  @Pure
+  public Either<Boolean, ReferenceOptions> getReferencesProvider() {
+    return this.referencesProvider;
+  }
+  
+  /**
+   * The server provides find references support.
+   */
+  public void setReferencesProvider(final Either<Boolean, ReferenceOptions> referencesProvider) {
+    this.referencesProvider = referencesProvider;
+  }
+  
+  public void setReferencesProvider(final Boolean referencesProvider) {
+    if (referencesProvider == null) {
+      this.referencesProvider = null;
+      return;
+    }
+    this.referencesProvider = Either.forLeft(referencesProvider);
+  }
+  
+  public void setReferencesProvider(final ReferenceOptions referencesProvider) {
+    if (referencesProvider == null) {
+      this.referencesProvider = null;
+      return;
+    }
+    this.referencesProvider = Either.forRight(referencesProvider);
+  }
+  
+  /**
+   * The server provides document highlight support.
+   */
+  @Pure
+  public Either<Boolean, DocumentHighlightOptions> getDocumentHighlightProvider() {
+    return this.documentHighlightProvider;
+  }
+  
+  /**
+   * The server provides document highlight support.
+   */
+  public void setDocumentHighlightProvider(final Either<Boolean, DocumentHighlightOptions> documentHighlightProvider) {
+    this.documentHighlightProvider = documentHighlightProvider;
+  }
+  
+  public void setDocumentHighlightProvider(final Boolean documentHighlightProvider) {
+    if (documentHighlightProvider == null) {
+      this.documentHighlightProvider = null;
+      return;
+    }
+    this.documentHighlightProvider = Either.forLeft(documentHighlightProvider);
+  }
+  
+  public void setDocumentHighlightProvider(final DocumentHighlightOptions documentHighlightProvider) {
+    if (documentHighlightProvider == null) {
+      this.documentHighlightProvider = null;
+      return;
+    }
+    this.documentHighlightProvider = Either.forRight(documentHighlightProvider);
+  }
+  
+  /**
+   * The server provides document symbol support.
+   */
+  @Pure
+  public Either<Boolean, DocumentSymbolOptions> getDocumentSymbolProvider() {
+    return this.documentSymbolProvider;
+  }
+  
+  /**
+   * The server provides document symbol support.
+   */
+  public void setDocumentSymbolProvider(final Either<Boolean, DocumentSymbolOptions> documentSymbolProvider) {
+    this.documentSymbolProvider = documentSymbolProvider;
+  }
+  
+  public void setDocumentSymbolProvider(final Boolean documentSymbolProvider) {
+    if (documentSymbolProvider == null) {
+      this.documentSymbolProvider = null;
+      return;
+    }
+    this.documentSymbolProvider = Either.forLeft(documentSymbolProvider);
+  }
+  
+  public void setDocumentSymbolProvider(final DocumentSymbolOptions documentSymbolProvider) {
+    if (documentSymbolProvider == null) {
+      this.documentSymbolProvider = null;
+      return;
+    }
+    this.documentSymbolProvider = Either.forRight(documentSymbolProvider);
+  }
+  
+  /**
+   * The server provides workspace symbol support.
+   */
+  @Pure
+  public Either<Boolean, WorkspaceSymbolOptions> getWorkspaceSymbolProvider() {
+    return this.workspaceSymbolProvider;
+  }
+  
+  /**
+   * The server provides workspace symbol support.
+   */
+  public void setWorkspaceSymbolProvider(final Either<Boolean, WorkspaceSymbolOptions> workspaceSymbolProvider) {
+    this.workspaceSymbolProvider = workspaceSymbolProvider;
+  }
+  
+  public void setWorkspaceSymbolProvider(final Boolean workspaceSymbolProvider) {
+    if (workspaceSymbolProvider == null) {
+      this.workspaceSymbolProvider = null;
+      return;
+    }
+    this.workspaceSymbolProvider = Either.forLeft(workspaceSymbolProvider);
+  }
+  
+  public void setWorkspaceSymbolProvider(final WorkspaceSymbolOptions workspaceSymbolProvider) {
+    if (workspaceSymbolProvider == null) {
+      this.workspaceSymbolProvider = null;
+      return;
+    }
+    this.workspaceSymbolProvider = Either.forRight(workspaceSymbolProvider);
+  }
+  
+  /**
+   * The server provides code actions. The {@link CodeActionOptions} return type is only
+   * valid if the client signals code action literal support via the property
+   * {@link CodeActionCapabilities#codeActionLiteralSupport}.
+   */
+  @Pure
+  public Either<Boolean, CodeActionOptions> getCodeActionProvider() {
+    return this.codeActionProvider;
+  }
+  
+  /**
+   * The server provides code actions. The {@link CodeActionOptions} return type is only
+   * valid if the client signals code action literal support via the property
+   * {@link CodeActionCapabilities#codeActionLiteralSupport}.
+   */
+  public void setCodeActionProvider(final Either<Boolean, CodeActionOptions> codeActionProvider) {
+    this.codeActionProvider = codeActionProvider;
+  }
+  
+  public void setCodeActionProvider(final Boolean codeActionProvider) {
+    if (codeActionProvider == null) {
+      this.codeActionProvider = null;
+      return;
+    }
+    this.codeActionProvider = Either.forLeft(codeActionProvider);
+  }
+  
+  public void setCodeActionProvider(final CodeActionOptions codeActionProvider) {
+    if (codeActionProvider == null) {
+      this.codeActionProvider = null;
+      return;
+    }
+    this.codeActionProvider = Either.forRight(codeActionProvider);
+  }
+  
+  /**
+   * The server provides code lens.
+   */
+  @Pure
+  public CodeLensOptions getCodeLensProvider() {
+    return this.codeLensProvider;
+  }
+  
+  /**
+   * The server provides code lens.
+   */
+  public void setCodeLensProvider(final CodeLensOptions codeLensProvider) {
+    this.codeLensProvider = codeLensProvider;
+  }
+  
+  /**
+   * The server provides document formatting.
+   */
+  @Pure
+  public Either<Boolean, DocumentFormattingOptions> getDocumentFormattingProvider() {
+    return this.documentFormattingProvider;
+  }
+  
+  /**
+   * The server provides document formatting.
+   */
+  public void setDocumentFormattingProvider(final Either<Boolean, DocumentFormattingOptions> documentFormattingProvider) {
+    this.documentFormattingProvider = documentFormattingProvider;
+  }
+  
+  public void setDocumentFormattingProvider(final Boolean documentFormattingProvider) {
+    if (documentFormattingProvider == null) {
+      this.documentFormattingProvider = null;
+      return;
+    }
+    this.documentFormattingProvider = Either.forLeft(documentFormattingProvider);
+  }
+  
+  public void setDocumentFormattingProvider(final DocumentFormattingOptions documentFormattingProvider) {
+    if (documentFormattingProvider == null) {
+      this.documentFormattingProvider = null;
+      return;
+    }
+    this.documentFormattingProvider = Either.forRight(documentFormattingProvider);
+  }
+  
+  /**
+   * The server provides document range formatting.
+   */
+  @Pure
+  public Either<Boolean, DocumentRangeFormattingOptions> getDocumentRangeFormattingProvider() {
+    return this.documentRangeFormattingProvider;
+  }
+  
+  /**
+   * The server provides document range formatting.
+   */
+  public void setDocumentRangeFormattingProvider(final Either<Boolean, DocumentRangeFormattingOptions> documentRangeFormattingProvider) {
+    this.documentRangeFormattingProvider = documentRangeFormattingProvider;
+  }
+  
+  public void setDocumentRangeFormattingProvider(final Boolean documentRangeFormattingProvider) {
+    if (documentRangeFormattingProvider == null) {
+      this.documentRangeFormattingProvider = null;
+      return;
+    }
+    this.documentRangeFormattingProvider = Either.forLeft(documentRangeFormattingProvider);
+  }
+  
+  public void setDocumentRangeFormattingProvider(final DocumentRangeFormattingOptions documentRangeFormattingProvider) {
+    if (documentRangeFormattingProvider == null) {
+      this.documentRangeFormattingProvider = null;
+      return;
+    }
+    this.documentRangeFormattingProvider = Either.forRight(documentRangeFormattingProvider);
+  }
+  
+  /**
+   * The server provides document formatting on typing.
+   */
+  @Pure
+  public DocumentOnTypeFormattingOptions getDocumentOnTypeFormattingProvider() {
+    return this.documentOnTypeFormattingProvider;
+  }
+  
+  /**
+   * The server provides document formatting on typing.
+   */
+  public void setDocumentOnTypeFormattingProvider(final DocumentOnTypeFormattingOptions documentOnTypeFormattingProvider) {
+    this.documentOnTypeFormattingProvider = documentOnTypeFormattingProvider;
+  }
+  
+  /**
+   * The server provides rename support.
+   */
+  @Pure
+  public Either<Boolean, RenameOptions> getRenameProvider() {
+    return this.renameProvider;
+  }
+  
+  /**
+   * The server provides rename support.
+   */
+  public void setRenameProvider(final Either<Boolean, RenameOptions> renameProvider) {
+    this.renameProvider = renameProvider;
+  }
+  
+  public void setRenameProvider(final Boolean renameProvider) {
+    if (renameProvider == null) {
+      this.renameProvider = null;
+      return;
+    }
+    this.renameProvider = Either.forLeft(renameProvider);
+  }
+  
+  public void setRenameProvider(final RenameOptions renameProvider) {
+    if (renameProvider == null) {
+      this.renameProvider = null;
+      return;
+    }
+    this.renameProvider = Either.forRight(renameProvider);
+  }
+  
+  /**
+   * The server provides document link support.
+   */
+  @Pure
+  public DocumentLinkOptions getDocumentLinkProvider() {
+    return this.documentLinkProvider;
+  }
+  
+  /**
+   * The server provides document link support.
+   */
+  public void setDocumentLinkProvider(final DocumentLinkOptions documentLinkProvider) {
+    this.documentLinkProvider = documentLinkProvider;
+  }
+  
+  /**
+   * The server provides color provider support.
+   * <p>
+   * Since 3.6.0
+   */
+  @Pure
+  public Either<Boolean, ColorProviderOptions> getColorProvider() {
+    return this.colorProvider;
+  }
+  
+  /**
+   * The server provides color provider support.
+   * <p>
+   * Since 3.6.0
+   */
+  public void setColorProvider(final Either<Boolean, ColorProviderOptions> colorProvider) {
+    this.colorProvider = colorProvider;
+  }
+  
+  public void setColorProvider(final Boolean colorProvider) {
+    if (colorProvider == null) {
+      this.colorProvider = null;
+      return;
+    }
+    this.colorProvider = Either.forLeft(colorProvider);
+  }
+  
+  public void setColorProvider(final ColorProviderOptions colorProvider) {
+    if (colorProvider == null) {
+      this.colorProvider = null;
+      return;
+    }
+    this.colorProvider = Either.forRight(colorProvider);
+  }
+  
+  /**
+   * The server provides folding provider support.
+   * <p>
+   * Since 3.10.0
+   */
+  @Pure
+  public Either<Boolean, FoldingRangeProviderOptions> getFoldingRangeProvider() {
+    return this.foldingRangeProvider;
+  }
+  
+  /**
+   * The server provides folding provider support.
+   * <p>
+   * Since 3.10.0
+   */
+  public void setFoldingRangeProvider(final Either<Boolean, FoldingRangeProviderOptions> foldingRangeProvider) {
+    this.foldingRangeProvider = foldingRangeProvider;
+  }
+  
+  public void setFoldingRangeProvider(final Boolean foldingRangeProvider) {
+    if (foldingRangeProvider == null) {
+      this.foldingRangeProvider = null;
+      return;
+    }
+    this.foldingRangeProvider = Either.forLeft(foldingRangeProvider);
+  }
+  
+  public void setFoldingRangeProvider(final FoldingRangeProviderOptions foldingRangeProvider) {
+    if (foldingRangeProvider == null) {
+      this.foldingRangeProvider = null;
+      return;
+    }
+    this.foldingRangeProvider = Either.forRight(foldingRangeProvider);
+  }
+  
+  /**
+   * The server provides go to declaration support.
+   * <p>
+   * Since 3.14.0
+   */
+  @Pure
+  public Either<Boolean, DeclarationRegistrationOptions> getDeclarationProvider() {
+    return this.declarationProvider;
+  }
+  
+  /**
+   * The server provides go to declaration support.
+   * <p>
+   * Since 3.14.0
+   */
+  public void setDeclarationProvider(final Either<Boolean, DeclarationRegistrationOptions> declarationProvider) {
+    this.declarationProvider = declarationProvider;
+  }
+  
+  public void setDeclarationProvider(final Boolean declarationProvider) {
+    if (declarationProvider == null) {
+      this.declarationProvider = null;
+      return;
+    }
+    this.declarationProvider = Either.forLeft(declarationProvider);
+  }
+  
+  public void setDeclarationProvider(final DeclarationRegistrationOptions declarationProvider) {
+    if (declarationProvider == null) {
+      this.declarationProvider = null;
+      return;
+    }
+    this.declarationProvider = Either.forRight(declarationProvider);
+  }
+  
+  /**
+   * The server provides execute command support.
+   */
+  @Pure
+  public ExecuteCommandOptions getExecuteCommandProvider() {
+    return this.executeCommandProvider;
+  }
+  
+  /**
+   * The server provides execute command support.
+   */
+  public void setExecuteCommandProvider(final ExecuteCommandOptions executeCommandProvider) {
+    this.executeCommandProvider = executeCommandProvider;
+  }
+  
+  /**
+   * Workspace specific server capabilities
+   */
+  @Pure
+  public WorkspaceServerCapabilities getWorkspace() {
+    return this.workspace;
+  }
+  
+  /**
+   * Workspace specific server capabilities
+   */
+  public void setWorkspace(final WorkspaceServerCapabilities workspace) {
+    this.workspace = workspace;
+  }
+  
+  /**
+   * Server capability for calculating super- and subtype hierarchies.
+   * The LS supports the type hierarchy language feature, if this capability is set to {@code true}.
+   * <p>
+   * <b>Note:</b> the <a href=
+   * "https://github.com/Microsoft/vscode-languageserver-node/pull/426">{@code textDocument/typeHierarchy}
+   * language feature</a> is not yet part of the official LSP specification.
+   */
+  @Pure
+  public Either<Boolean, StaticRegistrationOptions> getTypeHierarchyProvider() {
+    return this.typeHierarchyProvider;
+  }
+  
+  /**
+   * Server capability for calculating super- and subtype hierarchies.
+   * The LS supports the type hierarchy language feature, if this capability is set to {@code true}.
+   * <p>
+   * <b>Note:</b> the <a href=
+   * "https://github.com/Microsoft/vscode-languageserver-node/pull/426">{@code textDocument/typeHierarchy}
+   * language feature</a> is not yet part of the official LSP specification.
+   */
+  public void setTypeHierarchyProvider(final Either<Boolean, StaticRegistrationOptions> typeHierarchyProvider) {
+    this.typeHierarchyProvider = typeHierarchyProvider;
+  }
+  
+  public void setTypeHierarchyProvider(final Boolean typeHierarchyProvider) {
+    if (typeHierarchyProvider == null) {
+      this.typeHierarchyProvider = null;
+      return;
+    }
+    this.typeHierarchyProvider = Either.forLeft(typeHierarchyProvider);
+  }
+  
+  public void setTypeHierarchyProvider(final StaticRegistrationOptions typeHierarchyProvider) {
+    if (typeHierarchyProvider == null) {
+      this.typeHierarchyProvider = null;
+      return;
+    }
+    this.typeHierarchyProvider = Either.forRight(typeHierarchyProvider);
+  }
+  
+  /**
+   * The server provides Call Hierarchy support.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public Either<Boolean, CallHierarchyRegistrationOptions> getCallHierarchyProvider() {
+    return this.callHierarchyProvider;
+  }
+  
+  /**
+   * The server provides Call Hierarchy support.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setCallHierarchyProvider(final Either<Boolean, CallHierarchyRegistrationOptions> callHierarchyProvider) {
+    this.callHierarchyProvider = callHierarchyProvider;
+  }
+  
+  public void setCallHierarchyProvider(final Boolean callHierarchyProvider) {
+    if (callHierarchyProvider == null) {
+      this.callHierarchyProvider = null;
+      return;
+    }
+    this.callHierarchyProvider = Either.forLeft(callHierarchyProvider);
+  }
+  
+  public void setCallHierarchyProvider(final CallHierarchyRegistrationOptions callHierarchyProvider) {
+    if (callHierarchyProvider == null) {
+      this.callHierarchyProvider = null;
+      return;
+    }
+    this.callHierarchyProvider = Either.forRight(callHierarchyProvider);
+  }
+  
+  /**
+   * The server provides selection range support.
+   * <p>
+   * Since 3.15.0
+   */
+  @Pure
+  public Either<Boolean, SelectionRangeRegistrationOptions> getSelectionRangeProvider() {
+    return this.selectionRangeProvider;
+  }
+  
+  /**
+   * The server provides selection range support.
+   * <p>
+   * Since 3.15.0
+   */
+  public void setSelectionRangeProvider(final Either<Boolean, SelectionRangeRegistrationOptions> selectionRangeProvider) {
+    this.selectionRangeProvider = selectionRangeProvider;
+  }
+  
+  public void setSelectionRangeProvider(final Boolean selectionRangeProvider) {
+    if (selectionRangeProvider == null) {
+      this.selectionRangeProvider = null;
+      return;
+    }
+    this.selectionRangeProvider = Either.forLeft(selectionRangeProvider);
+  }
+  
+  public void setSelectionRangeProvider(final SelectionRangeRegistrationOptions selectionRangeProvider) {
+    if (selectionRangeProvider == null) {
+      this.selectionRangeProvider = null;
+      return;
+    }
+    this.selectionRangeProvider = Either.forRight(selectionRangeProvider);
+  }
+  
+  /**
+   * The server provides linked editing range support.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public Either<Boolean, LinkedEditingRangeRegistrationOptions> getLinkedEditingRangeProvider() {
+    return this.linkedEditingRangeProvider;
+  }
+  
+  /**
+   * The server provides linked editing range support.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setLinkedEditingRangeProvider(final Either<Boolean, LinkedEditingRangeRegistrationOptions> linkedEditingRangeProvider) {
+    this.linkedEditingRangeProvider = linkedEditingRangeProvider;
+  }
+  
+  public void setLinkedEditingRangeProvider(final Boolean linkedEditingRangeProvider) {
+    if (linkedEditingRangeProvider == null) {
+      this.linkedEditingRangeProvider = null;
+      return;
+    }
+    this.linkedEditingRangeProvider = Either.forLeft(linkedEditingRangeProvider);
+  }
+  
+  public void setLinkedEditingRangeProvider(final LinkedEditingRangeRegistrationOptions linkedEditingRangeProvider) {
+    if (linkedEditingRangeProvider == null) {
+      this.linkedEditingRangeProvider = null;
+      return;
+    }
+    this.linkedEditingRangeProvider = Either.forRight(linkedEditingRangeProvider);
+  }
+  
+  /**
+   * The server provides semantic tokens support.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public SemanticTokensWithRegistrationOptions getSemanticTokensProvider() {
+    return this.semanticTokensProvider;
+  }
+  
+  /**
+   * The server provides semantic tokens support.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setSemanticTokensProvider(final SemanticTokensWithRegistrationOptions semanticTokensProvider) {
+    this.semanticTokensProvider = semanticTokensProvider;
+  }
+  
+  /**
+   * Whether server provides moniker support.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public Either<Boolean, MonikerRegistrationOptions> getMonikerProvider() {
+    return this.monikerProvider;
+  }
+  
+  /**
+   * Whether server provides moniker support.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setMonikerProvider(final Either<Boolean, MonikerRegistrationOptions> monikerProvider) {
+    this.monikerProvider = monikerProvider;
+  }
+  
+  public void setMonikerProvider(final Boolean monikerProvider) {
+    if (monikerProvider == null) {
+      this.monikerProvider = null;
+      return;
+    }
+    this.monikerProvider = Either.forLeft(monikerProvider);
+  }
+  
+  public void setMonikerProvider(final MonikerRegistrationOptions monikerProvider) {
+    if (monikerProvider == null) {
+      this.monikerProvider = null;
+      return;
+    }
+    this.monikerProvider = Either.forRight(monikerProvider);
+  }
+  
+  /**
+   * Experimental server capabilities.
+   */
+  @Pure
+  public Object getExperimental() {
+    return this.experimental;
+  }
+  
+  /**
+   * Experimental server capabilities.
+   */
+  public void setExperimental(final Object experimental) {
+    this.experimental = experimental;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("textDocumentSync", this.textDocumentSync);
+    b.add("hoverProvider", this.hoverProvider);
+    b.add("completionProvider", this.completionProvider);
+    b.add("signatureHelpProvider", this.signatureHelpProvider);
+    b.add("definitionProvider", this.definitionProvider);
+    b.add("typeDefinitionProvider", this.typeDefinitionProvider);
+    b.add("implementationProvider", this.implementationProvider);
+    b.add("referencesProvider", this.referencesProvider);
+    b.add("documentHighlightProvider", this.documentHighlightProvider);
+    b.add("documentSymbolProvider", this.documentSymbolProvider);
+    b.add("workspaceSymbolProvider", this.workspaceSymbolProvider);
+    b.add("codeActionProvider", this.codeActionProvider);
+    b.add("codeLensProvider", this.codeLensProvider);
+    b.add("documentFormattingProvider", this.documentFormattingProvider);
+    b.add("documentRangeFormattingProvider", this.documentRangeFormattingProvider);
+    b.add("documentOnTypeFormattingProvider", this.documentOnTypeFormattingProvider);
+    b.add("renameProvider", this.renameProvider);
+    b.add("documentLinkProvider", this.documentLinkProvider);
+    b.add("colorProvider", this.colorProvider);
+    b.add("foldingRangeProvider", this.foldingRangeProvider);
+    b.add("declarationProvider", this.declarationProvider);
+    b.add("executeCommandProvider", this.executeCommandProvider);
+    b.add("workspace", this.workspace);
+    b.add("typeHierarchyProvider", this.typeHierarchyProvider);
+    b.add("callHierarchyProvider", this.callHierarchyProvider);
+    b.add("selectionRangeProvider", this.selectionRangeProvider);
+    b.add("linkedEditingRangeProvider", this.linkedEditingRangeProvider);
+    b.add("semanticTokensProvider", this.semanticTokensProvider);
+    b.add("monikerProvider", this.monikerProvider);
+    b.add("experimental", this.experimental);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ServerCapabilities other = (ServerCapabilities) obj;
+    if (this.textDocumentSync == null) {
+      if (other.textDocumentSync != null)
+        return false;
+    } else if (!this.textDocumentSync.equals(other.textDocumentSync))
+      return false;
+    if (this.hoverProvider == null) {
+      if (other.hoverProvider != null)
+        return false;
+    } else if (!this.hoverProvider.equals(other.hoverProvider))
+      return false;
+    if (this.completionProvider == null) {
+      if (other.completionProvider != null)
+        return false;
+    } else if (!this.completionProvider.equals(other.completionProvider))
+      return false;
+    if (this.signatureHelpProvider == null) {
+      if (other.signatureHelpProvider != null)
+        return false;
+    } else if (!this.signatureHelpProvider.equals(other.signatureHelpProvider))
+      return false;
+    if (this.definitionProvider == null) {
+      if (other.definitionProvider != null)
+        return false;
+    } else if (!this.definitionProvider.equals(other.definitionProvider))
+      return false;
+    if (this.typeDefinitionProvider == null) {
+      if (other.typeDefinitionProvider != null)
+        return false;
+    } else if (!this.typeDefinitionProvider.equals(other.typeDefinitionProvider))
+      return false;
+    if (this.implementationProvider == null) {
+      if (other.implementationProvider != null)
+        return false;
+    } else if (!this.implementationProvider.equals(other.implementationProvider))
+      return false;
+    if (this.referencesProvider == null) {
+      if (other.referencesProvider != null)
+        return false;
+    } else if (!this.referencesProvider.equals(other.referencesProvider))
+      return false;
+    if (this.documentHighlightProvider == null) {
+      if (other.documentHighlightProvider != null)
+        return false;
+    } else if (!this.documentHighlightProvider.equals(other.documentHighlightProvider))
+      return false;
+    if (this.documentSymbolProvider == null) {
+      if (other.documentSymbolProvider != null)
+        return false;
+    } else if (!this.documentSymbolProvider.equals(other.documentSymbolProvider))
+      return false;
+    if (this.workspaceSymbolProvider == null) {
+      if (other.workspaceSymbolProvider != null)
+        return false;
+    } else if (!this.workspaceSymbolProvider.equals(other.workspaceSymbolProvider))
+      return false;
+    if (this.codeActionProvider == null) {
+      if (other.codeActionProvider != null)
+        return false;
+    } else if (!this.codeActionProvider.equals(other.codeActionProvider))
+      return false;
+    if (this.codeLensProvider == null) {
+      if (other.codeLensProvider != null)
+        return false;
+    } else if (!this.codeLensProvider.equals(other.codeLensProvider))
+      return false;
+    if (this.documentFormattingProvider == null) {
+      if (other.documentFormattingProvider != null)
+        return false;
+    } else if (!this.documentFormattingProvider.equals(other.documentFormattingProvider))
+      return false;
+    if (this.documentRangeFormattingProvider == null) {
+      if (other.documentRangeFormattingProvider != null)
+        return false;
+    } else if (!this.documentRangeFormattingProvider.equals(other.documentRangeFormattingProvider))
+      return false;
+    if (this.documentOnTypeFormattingProvider == null) {
+      if (other.documentOnTypeFormattingProvider != null)
+        return false;
+    } else if (!this.documentOnTypeFormattingProvider.equals(other.documentOnTypeFormattingProvider))
+      return false;
+    if (this.renameProvider == null) {
+      if (other.renameProvider != null)
+        return false;
+    } else if (!this.renameProvider.equals(other.renameProvider))
+      return false;
+    if (this.documentLinkProvider == null) {
+      if (other.documentLinkProvider != null)
+        return false;
+    } else if (!this.documentLinkProvider.equals(other.documentLinkProvider))
+      return false;
+    if (this.colorProvider == null) {
+      if (other.colorProvider != null)
+        return false;
+    } else if (!this.colorProvider.equals(other.colorProvider))
+      return false;
+    if (this.foldingRangeProvider == null) {
+      if (other.foldingRangeProvider != null)
+        return false;
+    } else if (!this.foldingRangeProvider.equals(other.foldingRangeProvider))
+      return false;
+    if (this.declarationProvider == null) {
+      if (other.declarationProvider != null)
+        return false;
+    } else if (!this.declarationProvider.equals(other.declarationProvider))
+      return false;
+    if (this.executeCommandProvider == null) {
+      if (other.executeCommandProvider != null)
+        return false;
+    } else if (!this.executeCommandProvider.equals(other.executeCommandProvider))
+      return false;
+    if (this.workspace == null) {
+      if (other.workspace != null)
+        return false;
+    } else if (!this.workspace.equals(other.workspace))
+      return false;
+    if (this.typeHierarchyProvider == null) {
+      if (other.typeHierarchyProvider != null)
+        return false;
+    } else if (!this.typeHierarchyProvider.equals(other.typeHierarchyProvider))
+      return false;
+    if (this.callHierarchyProvider == null) {
+      if (other.callHierarchyProvider != null)
+        return false;
+    } else if (!this.callHierarchyProvider.equals(other.callHierarchyProvider))
+      return false;
+    if (this.selectionRangeProvider == null) {
+      if (other.selectionRangeProvider != null)
+        return false;
+    } else if (!this.selectionRangeProvider.equals(other.selectionRangeProvider))
+      return false;
+    if (this.linkedEditingRangeProvider == null) {
+      if (other.linkedEditingRangeProvider != null)
+        return false;
+    } else if (!this.linkedEditingRangeProvider.equals(other.linkedEditingRangeProvider))
+      return false;
+    if (this.semanticTokensProvider == null) {
+      if (other.semanticTokensProvider != null)
+        return false;
+    } else if (!this.semanticTokensProvider.equals(other.semanticTokensProvider))
+      return false;
+    if (this.monikerProvider == null) {
+      if (other.monikerProvider != null)
+        return false;
+    } else if (!this.monikerProvider.equals(other.monikerProvider))
+      return false;
+    if (this.experimental == null) {
+      if (other.experimental != null)
+        return false;
+    } else if (!this.experimental.equals(other.experimental))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.textDocumentSync== null) ? 0 : this.textDocumentSync.hashCode());
+    result = prime * result + ((this.hoverProvider== null) ? 0 : this.hoverProvider.hashCode());
+    result = prime * result + ((this.completionProvider== null) ? 0 : this.completionProvider.hashCode());
+    result = prime * result + ((this.signatureHelpProvider== null) ? 0 : this.signatureHelpProvider.hashCode());
+    result = prime * result + ((this.definitionProvider== null) ? 0 : this.definitionProvider.hashCode());
+    result = prime * result + ((this.typeDefinitionProvider== null) ? 0 : this.typeDefinitionProvider.hashCode());
+    result = prime * result + ((this.implementationProvider== null) ? 0 : this.implementationProvider.hashCode());
+    result = prime * result + ((this.referencesProvider== null) ? 0 : this.referencesProvider.hashCode());
+    result = prime * result + ((this.documentHighlightProvider== null) ? 0 : this.documentHighlightProvider.hashCode());
+    result = prime * result + ((this.documentSymbolProvider== null) ? 0 : this.documentSymbolProvider.hashCode());
+    result = prime * result + ((this.workspaceSymbolProvider== null) ? 0 : this.workspaceSymbolProvider.hashCode());
+    result = prime * result + ((this.codeActionProvider== null) ? 0 : this.codeActionProvider.hashCode());
+    result = prime * result + ((this.codeLensProvider== null) ? 0 : this.codeLensProvider.hashCode());
+    result = prime * result + ((this.documentFormattingProvider== null) ? 0 : this.documentFormattingProvider.hashCode());
+    result = prime * result + ((this.documentRangeFormattingProvider== null) ? 0 : this.documentRangeFormattingProvider.hashCode());
+    result = prime * result + ((this.documentOnTypeFormattingProvider== null) ? 0 : this.documentOnTypeFormattingProvider.hashCode());
+    result = prime * result + ((this.renameProvider== null) ? 0 : this.renameProvider.hashCode());
+    result = prime * result + ((this.documentLinkProvider== null) ? 0 : this.documentLinkProvider.hashCode());
+    result = prime * result + ((this.colorProvider== null) ? 0 : this.colorProvider.hashCode());
+    result = prime * result + ((this.foldingRangeProvider== null) ? 0 : this.foldingRangeProvider.hashCode());
+    result = prime * result + ((this.declarationProvider== null) ? 0 : this.declarationProvider.hashCode());
+    result = prime * result + ((this.executeCommandProvider== null) ? 0 : this.executeCommandProvider.hashCode());
+    result = prime * result + ((this.workspace== null) ? 0 : this.workspace.hashCode());
+    result = prime * result + ((this.typeHierarchyProvider== null) ? 0 : this.typeHierarchyProvider.hashCode());
+    result = prime * result + ((this.callHierarchyProvider== null) ? 0 : this.callHierarchyProvider.hashCode());
+    result = prime * result + ((this.selectionRangeProvider== null) ? 0 : this.selectionRangeProvider.hashCode());
+    result = prime * result + ((this.linkedEditingRangeProvider== null) ? 0 : this.linkedEditingRangeProvider.hashCode());
+    result = prime * result + ((this.semanticTokensProvider== null) ? 0 : this.semanticTokensProvider.hashCode());
+    result = prime * result + ((this.monikerProvider== null) ? 0 : this.monikerProvider.hashCode());
+    return prime * result + ((this.experimental== null) ? 0 : this.experimental.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ServerInfo.java b/java/org/eclipse/lsp4j/ServerInfo.java
new file mode 100644
index 0000000..d759811
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ServerInfo.java
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Information about the server.
+ * <p>
+ * Since 3.15.0
+ */
+@SuppressWarnings("all")
+public class ServerInfo {
+  /**
+   * The name of the server as defined by the server.
+   */
+  @NonNull
+  private String name;
+  
+  /**
+   * The server's version as defined by the server.
+   */
+  private String version;
+  
+  public ServerInfo() {
+  }
+  
+  public ServerInfo(@NonNull final String name) {
+    this.name = Preconditions.<String>checkNotNull(name, "name");
+  }
+  
+  public ServerInfo(@NonNull final String name, final String version) {
+    this(name);
+    this.version = version;
+  }
+  
+  /**
+   * The name of the server as defined by the server.
+   */
+  @Pure
+  @NonNull
+  public String getName() {
+    return this.name;
+  }
+  
+  /**
+   * The name of the server as defined by the server.
+   */
+  public void setName(@NonNull final String name) {
+    this.name = Preconditions.checkNotNull(name, "name");
+  }
+  
+  /**
+   * The server's version as defined by the server.
+   */
+  @Pure
+  public String getVersion() {
+    return this.version;
+  }
+  
+  /**
+   * The server's version as defined by the server.
+   */
+  public void setVersion(final String version) {
+    this.version = version;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("name", this.name);
+    b.add("version", this.version);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ServerInfo other = (ServerInfo) obj;
+    if (this.name == null) {
+      if (other.name != null)
+        return false;
+    } else if (!this.name.equals(other.name))
+      return false;
+    if (this.version == null) {
+      if (other.version != null)
+        return false;
+    } else if (!this.version.equals(other.version))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.name== null) ? 0 : this.name.hashCode());
+    return prime * result + ((this.version== null) ? 0 : this.version.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SetTraceParams.java b/java/org/eclipse/lsp4j/SetTraceParams.java
new file mode 100644
index 0000000..f204c89
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SetTraceParams.java
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A notification that should be used by the client to modify the trace setting of the server.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class SetTraceParams {
+  /**
+   * The new value that should be assigned to the trace setting.
+   * For values, see {@link TraceValue}.
+   */
+  @NonNull
+  private String value;
+  
+  public SetTraceParams() {
+  }
+  
+  public SetTraceParams(@NonNull final String value) {
+    this.value = Preconditions.<String>checkNotNull(value, "value");
+  }
+  
+  /**
+   * The new value that should be assigned to the trace setting.
+   * For values, see {@link TraceValue}.
+   */
+  @Pure
+  @NonNull
+  public String getValue() {
+    return this.value;
+  }
+  
+  /**
+   * The new value that should be assigned to the trace setting.
+   * For values, see {@link TraceValue}.
+   */
+  public void setValue(@NonNull final String value) {
+    this.value = Preconditions.checkNotNull(value, "value");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("value", this.value);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SetTraceParams other = (SetTraceParams) obj;
+    if (this.value == null) {
+      if (other.value != null)
+        return false;
+    } else if (!this.value.equals(other.value))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.value== null) ? 0 : this.value.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ShowDocumentCapabilities.java b/java/org/eclipse/lsp4j/ShowDocumentCapabilities.java
new file mode 100644
index 0000000..6139aee
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ShowDocumentCapabilities.java
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Client capabilities for the show document request.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class ShowDocumentCapabilities {
+  /**
+   * The client has support for the show document
+   * request.
+   */
+  private boolean support;
+  
+  public ShowDocumentCapabilities() {
+  }
+  
+  public ShowDocumentCapabilities(final boolean support) {
+    this.support = support;
+  }
+  
+  /**
+   * The client has support for the show document
+   * request.
+   */
+  @Pure
+  public boolean isSupport() {
+    return this.support;
+  }
+  
+  /**
+   * The client has support for the show document
+   * request.
+   */
+  public void setSupport(final boolean support) {
+    this.support = support;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("support", this.support);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ShowDocumentCapabilities other = (ShowDocumentCapabilities) obj;
+    if (other.support != this.support)
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + (this.support ? 1231 : 1237);
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ShowDocumentParams.java b/java/org/eclipse/lsp4j/ShowDocumentParams.java
new file mode 100644
index 0000000..0503888
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ShowDocumentParams.java
@@ -0,0 +1,197 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Params to show a document.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class ShowDocumentParams {
+  /**
+   * The document uri to show.
+   */
+  @NonNull
+  private String uri;
+  
+  /**
+   * Indicates to show the resource in an external program.
+   * To show for example <a href="https://www.eclipse.org/">
+   * https://www.eclipse.org/</a>
+   * in the default WEB browser set to {@code true}.
+   */
+  private Boolean external;
+  
+  /**
+   * An optional property to indicate whether the editor
+   * showing the document should take focus or not.
+   * Clients might ignore this property if an external
+   * program is started.
+   */
+  private Boolean takeFocus;
+  
+  /**
+   * An optional selection range if the document is a text
+   * document. Clients might ignore the property if an
+   * external program is started or the file is not a text
+   * file.
+   */
+  private Range selection;
+  
+  public ShowDocumentParams() {
+  }
+  
+  public ShowDocumentParams(@NonNull final String uri) {
+    this.uri = Preconditions.<String>checkNotNull(uri, "uri");
+  }
+  
+  /**
+   * The document uri to show.
+   */
+  @Pure
+  @NonNull
+  public String getUri() {
+    return this.uri;
+  }
+  
+  /**
+   * The document uri to show.
+   */
+  public void setUri(@NonNull final String uri) {
+    this.uri = Preconditions.checkNotNull(uri, "uri");
+  }
+  
+  /**
+   * Indicates to show the resource in an external program.
+   * To show for example <a href="https://www.eclipse.org/">
+   * https://www.eclipse.org/</a>
+   * in the default WEB browser set to {@code true}.
+   */
+  @Pure
+  public Boolean getExternal() {
+    return this.external;
+  }
+  
+  /**
+   * Indicates to show the resource in an external program.
+   * To show for example <a href="https://www.eclipse.org/">
+   * https://www.eclipse.org/</a>
+   * in the default WEB browser set to {@code true}.
+   */
+  public void setExternal(final Boolean external) {
+    this.external = external;
+  }
+  
+  /**
+   * An optional property to indicate whether the editor
+   * showing the document should take focus or not.
+   * Clients might ignore this property if an external
+   * program is started.
+   */
+  @Pure
+  public Boolean getTakeFocus() {
+    return this.takeFocus;
+  }
+  
+  /**
+   * An optional property to indicate whether the editor
+   * showing the document should take focus or not.
+   * Clients might ignore this property if an external
+   * program is started.
+   */
+  public void setTakeFocus(final Boolean takeFocus) {
+    this.takeFocus = takeFocus;
+  }
+  
+  /**
+   * An optional selection range if the document is a text
+   * document. Clients might ignore the property if an
+   * external program is started or the file is not a text
+   * file.
+   */
+  @Pure
+  public Range getSelection() {
+    return this.selection;
+  }
+  
+  /**
+   * An optional selection range if the document is a text
+   * document. Clients might ignore the property if an
+   * external program is started or the file is not a text
+   * file.
+   */
+  public void setSelection(final Range selection) {
+    this.selection = selection;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("uri", this.uri);
+    b.add("external", this.external);
+    b.add("takeFocus", this.takeFocus);
+    b.add("selection", this.selection);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ShowDocumentParams other = (ShowDocumentParams) obj;
+    if (this.uri == null) {
+      if (other.uri != null)
+        return false;
+    } else if (!this.uri.equals(other.uri))
+      return false;
+    if (this.external == null) {
+      if (other.external != null)
+        return false;
+    } else if (!this.external.equals(other.external))
+      return false;
+    if (this.takeFocus == null) {
+      if (other.takeFocus != null)
+        return false;
+    } else if (!this.takeFocus.equals(other.takeFocus))
+      return false;
+    if (this.selection == null) {
+      if (other.selection != null)
+        return false;
+    } else if (!this.selection.equals(other.selection))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.uri== null) ? 0 : this.uri.hashCode());
+    result = prime * result + ((this.external== null) ? 0 : this.external.hashCode());
+    result = prime * result + ((this.takeFocus== null) ? 0 : this.takeFocus.hashCode());
+    return prime * result + ((this.selection== null) ? 0 : this.selection.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ShowDocumentResult.java b/java/org/eclipse/lsp4j/ShowDocumentResult.java
new file mode 100644
index 0000000..54ea48c
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ShowDocumentResult.java
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The result of an show document request.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class ShowDocumentResult {
+  /**
+   * A boolean indicating if the show was successful.
+   */
+  private boolean success;
+  
+  public ShowDocumentResult() {
+  }
+  
+  public ShowDocumentResult(final boolean success) {
+    this.success = success;
+  }
+  
+  /**
+   * A boolean indicating if the show was successful.
+   */
+  @Pure
+  public boolean isSuccess() {
+    return this.success;
+  }
+  
+  /**
+   * A boolean indicating if the show was successful.
+   */
+  public void setSuccess(final boolean success) {
+    this.success = success;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("success", this.success);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ShowDocumentResult other = (ShowDocumentResult) obj;
+    if (other.success != this.success)
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + (this.success ? 1231 : 1237);
+  }
+}
diff --git a/java/org/eclipse/lsp4j/ShowMessageRequestParams.java b/java/org/eclipse/lsp4j/ShowMessageRequestParams.java
new file mode 100644
index 0000000..904c4e9
--- /dev/null
+++ b/java/org/eclipse/lsp4j/ShowMessageRequestParams.java
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.MessageActionItem;
+import org.eclipse.lsp4j.MessageParams;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The show message request is sent from a server to a client to ask the client to display a particular message in the
+ * user class. In addition to the show message notification the request allows to pass actions and to wait for an
+ * answer from the client.
+ */
+@SuppressWarnings("all")
+public class ShowMessageRequestParams extends MessageParams {
+  /**
+   * The message action items to present.
+   */
+  private List<MessageActionItem> actions;
+  
+  public ShowMessageRequestParams() {
+  }
+  
+  public ShowMessageRequestParams(final List<MessageActionItem> actions) {
+    this.actions = actions;
+  }
+  
+  /**
+   * The message action items to present.
+   */
+  @Pure
+  public List<MessageActionItem> getActions() {
+    return this.actions;
+  }
+  
+  /**
+   * The message action items to present.
+   */
+  public void setActions(final List<MessageActionItem> actions) {
+    this.actions = actions;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("actions", this.actions);
+    b.add("type", getType());
+    b.add("message", getMessage());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    ShowMessageRequestParams other = (ShowMessageRequestParams) obj;
+    if (this.actions == null) {
+      if (other.actions != null)
+        return false;
+    } else if (!this.actions.equals(other.actions))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.actions== null) ? 0 : this.actions.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SignatureHelp.java b/java/org/eclipse/lsp4j/SignatureHelp.java
new file mode 100644
index 0000000..a30d5e3
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SignatureHelp.java
@@ -0,0 +1,190 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.lsp4j.SignatureInformation;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Signature help represents the signature of something callable. There can be multiple signature but only one
+ * active and only one active parameter.
+ */
+@SuppressWarnings("all")
+public class SignatureHelp {
+  /**
+   * One or more signatures.
+   */
+  @NonNull
+  private List<SignatureInformation> signatures;
+  
+  /**
+   * The active signature. If omitted or the value lies outside the
+   * range of {@link #signatures} the value defaults to zero or is ignored if
+   * the {@code SignatureHelp} has no signatures. Whenever possible implementors should
+   * make an active decision about the active signature and shouldn't
+   * rely on a default value.
+   * <p>
+   * In future version of the protocol this property might become
+   * mandatory to better express this.
+   */
+  private Integer activeSignature;
+  
+  /**
+   * The active parameter of the active signature. If omitted or the value
+   * lies outside the range of {@code signatures[activeSignature].parameters}
+   * defaults to 0 if the active signature has parameters. If
+   * the active signature has no parameters it is ignored.
+   * <p>
+   * In future version of the protocol this property might become
+   * mandatory to better express the active parameter if the
+   * active signature does have any.
+   */
+  private Integer activeParameter;
+  
+  public SignatureHelp() {
+    ArrayList<SignatureInformation> _arrayList = new ArrayList<SignatureInformation>();
+    this.signatures = _arrayList;
+  }
+  
+  public SignatureHelp(@NonNull final List<SignatureInformation> signatures, final Integer activeSignature, final Integer activeParameter) {
+    this.signatures = Preconditions.<List<SignatureInformation>>checkNotNull(signatures, "signatures");
+    this.activeSignature = activeSignature;
+    this.activeParameter = activeParameter;
+  }
+  
+  /**
+   * One or more signatures.
+   */
+  @Pure
+  @NonNull
+  public List<SignatureInformation> getSignatures() {
+    return this.signatures;
+  }
+  
+  /**
+   * One or more signatures.
+   */
+  public void setSignatures(@NonNull final List<SignatureInformation> signatures) {
+    this.signatures = Preconditions.checkNotNull(signatures, "signatures");
+  }
+  
+  /**
+   * The active signature. If omitted or the value lies outside the
+   * range of {@link #signatures} the value defaults to zero or is ignored if
+   * the {@code SignatureHelp} has no signatures. Whenever possible implementors should
+   * make an active decision about the active signature and shouldn't
+   * rely on a default value.
+   * <p>
+   * In future version of the protocol this property might become
+   * mandatory to better express this.
+   */
+  @Pure
+  public Integer getActiveSignature() {
+    return this.activeSignature;
+  }
+  
+  /**
+   * The active signature. If omitted or the value lies outside the
+   * range of {@link #signatures} the value defaults to zero or is ignored if
+   * the {@code SignatureHelp} has no signatures. Whenever possible implementors should
+   * make an active decision about the active signature and shouldn't
+   * rely on a default value.
+   * <p>
+   * In future version of the protocol this property might become
+   * mandatory to better express this.
+   */
+  public void setActiveSignature(final Integer activeSignature) {
+    this.activeSignature = activeSignature;
+  }
+  
+  /**
+   * The active parameter of the active signature. If omitted or the value
+   * lies outside the range of {@code signatures[activeSignature].parameters}
+   * defaults to 0 if the active signature has parameters. If
+   * the active signature has no parameters it is ignored.
+   * <p>
+   * In future version of the protocol this property might become
+   * mandatory to better express the active parameter if the
+   * active signature does have any.
+   */
+  @Pure
+  public Integer getActiveParameter() {
+    return this.activeParameter;
+  }
+  
+  /**
+   * The active parameter of the active signature. If omitted or the value
+   * lies outside the range of {@code signatures[activeSignature].parameters}
+   * defaults to 0 if the active signature has parameters. If
+   * the active signature has no parameters it is ignored.
+   * <p>
+   * In future version of the protocol this property might become
+   * mandatory to better express the active parameter if the
+   * active signature does have any.
+   */
+  public void setActiveParameter(final Integer activeParameter) {
+    this.activeParameter = activeParameter;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("signatures", this.signatures);
+    b.add("activeSignature", this.activeSignature);
+    b.add("activeParameter", this.activeParameter);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SignatureHelp other = (SignatureHelp) obj;
+    if (this.signatures == null) {
+      if (other.signatures != null)
+        return false;
+    } else if (!this.signatures.equals(other.signatures))
+      return false;
+    if (this.activeSignature == null) {
+      if (other.activeSignature != null)
+        return false;
+    } else if (!this.activeSignature.equals(other.activeSignature))
+      return false;
+    if (this.activeParameter == null) {
+      if (other.activeParameter != null)
+        return false;
+    } else if (!this.activeParameter.equals(other.activeParameter))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.signatures== null) ? 0 : this.signatures.hashCode());
+    result = prime * result + ((this.activeSignature== null) ? 0 : this.activeSignature.hashCode());
+    return prime * result + ((this.activeParameter== null) ? 0 : this.activeParameter.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SignatureHelpCapabilities.java b/java/org/eclipse/lsp4j/SignatureHelpCapabilities.java
new file mode 100644
index 0000000..f8857fe
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SignatureHelpCapabilities.java
@@ -0,0 +1,134 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.lsp4j.SignatureInformationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the `textDocument/signatureHelp`
+ */
+@SuppressWarnings("all")
+public class SignatureHelpCapabilities extends DynamicRegistrationCapabilities {
+  /**
+   * The client supports the following {@link SignatureInformation}
+   * specific properties.
+   */
+  private SignatureInformationCapabilities signatureInformation;
+  
+  /**
+   * The client supports to send additional context information for a
+   * `textDocument/signatureHelp` request. A client that opts into
+   * contextSupport will also support {@link SignatureHelpOptions#retriggerCharacters}.
+   * <p>
+   * Since 3.15.0
+   */
+  private Boolean contextSupport;
+  
+  public SignatureHelpCapabilities() {
+  }
+  
+  public SignatureHelpCapabilities(final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+  }
+  
+  public SignatureHelpCapabilities(final SignatureInformationCapabilities signatureInformation, final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+    this.signatureInformation = signatureInformation;
+  }
+  
+  /**
+   * The client supports the following {@link SignatureInformation}
+   * specific properties.
+   */
+  @Pure
+  public SignatureInformationCapabilities getSignatureInformation() {
+    return this.signatureInformation;
+  }
+  
+  /**
+   * The client supports the following {@link SignatureInformation}
+   * specific properties.
+   */
+  public void setSignatureInformation(final SignatureInformationCapabilities signatureInformation) {
+    this.signatureInformation = signatureInformation;
+  }
+  
+  /**
+   * The client supports to send additional context information for a
+   * `textDocument/signatureHelp` request. A client that opts into
+   * contextSupport will also support {@link SignatureHelpOptions#retriggerCharacters}.
+   * <p>
+   * Since 3.15.0
+   */
+  @Pure
+  public Boolean getContextSupport() {
+    return this.contextSupport;
+  }
+  
+  /**
+   * The client supports to send additional context information for a
+   * `textDocument/signatureHelp` request. A client that opts into
+   * contextSupport will also support {@link SignatureHelpOptions#retriggerCharacters}.
+   * <p>
+   * Since 3.15.0
+   */
+  public void setContextSupport(final Boolean contextSupport) {
+    this.contextSupport = contextSupport;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("signatureInformation", this.signatureInformation);
+    b.add("contextSupport", this.contextSupport);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    SignatureHelpCapabilities other = (SignatureHelpCapabilities) obj;
+    if (this.signatureInformation == null) {
+      if (other.signatureInformation != null)
+        return false;
+    } else if (!this.signatureInformation.equals(other.signatureInformation))
+      return false;
+    if (this.contextSupport == null) {
+      if (other.contextSupport != null)
+        return false;
+    } else if (!this.contextSupport.equals(other.contextSupport))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.signatureInformation== null) ? 0 : this.signatureInformation.hashCode());
+    return prime * result + ((this.contextSupport== null) ? 0 : this.contextSupport.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SignatureHelpContext.java b/java/org/eclipse/lsp4j/SignatureHelpContext.java
new file mode 100644
index 0000000..6e7f7d2
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SignatureHelpContext.java
@@ -0,0 +1,193 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.SignatureHelp;
+import org.eclipse.lsp4j.SignatureHelpTriggerKind;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Additional information about the context in which a signature help request was triggered.
+ * <p>
+ * Since 3.15.0
+ */
+@SuppressWarnings("all")
+public class SignatureHelpContext {
+  /**
+   * Action that caused signature help to be triggered.
+   */
+  @NonNull
+  private SignatureHelpTriggerKind triggerKind;
+  
+  /**
+   * Character that caused signature help to be triggered.
+   * <p>
+   * This is undefined when {@link #triggerKind} is not {@link SignatureHelpTriggerKind#TriggerCharacter}
+   */
+  private String triggerCharacter;
+  
+  /**
+   * {@code true} if signature help was already showing when it was triggered.
+   * <p>
+   * Retriggers occur when the signature help is already active and can be caused by actions such as
+   * typing a trigger character, a cursor move, or document content changes.
+   */
+  private boolean isRetrigger;
+  
+  /**
+   * The currently active {@link SignatureHelp}.
+   * <p>
+   * The `activeSignatureHelp` has its {@link SignatureHelp#activeSignature} field updated based on
+   * the user navigating through available signatures.
+   */
+  private SignatureHelp activeSignatureHelp;
+  
+  public SignatureHelpContext() {
+  }
+  
+  public SignatureHelpContext(@NonNull final SignatureHelpTriggerKind triggerKind, final boolean isRetrigger) {
+    this.triggerKind = Preconditions.<SignatureHelpTriggerKind>checkNotNull(triggerKind, "triggerKind");
+    this.isRetrigger = isRetrigger;
+  }
+  
+  /**
+   * Action that caused signature help to be triggered.
+   */
+  @Pure
+  @NonNull
+  public SignatureHelpTriggerKind getTriggerKind() {
+    return this.triggerKind;
+  }
+  
+  /**
+   * Action that caused signature help to be triggered.
+   */
+  public void setTriggerKind(@NonNull final SignatureHelpTriggerKind triggerKind) {
+    this.triggerKind = Preconditions.checkNotNull(triggerKind, "triggerKind");
+  }
+  
+  /**
+   * Character that caused signature help to be triggered.
+   * <p>
+   * This is undefined when {@link #triggerKind} is not {@link SignatureHelpTriggerKind#TriggerCharacter}
+   */
+  @Pure
+  public String getTriggerCharacter() {
+    return this.triggerCharacter;
+  }
+  
+  /**
+   * Character that caused signature help to be triggered.
+   * <p>
+   * This is undefined when {@link #triggerKind} is not {@link SignatureHelpTriggerKind#TriggerCharacter}
+   */
+  public void setTriggerCharacter(final String triggerCharacter) {
+    this.triggerCharacter = triggerCharacter;
+  }
+  
+  /**
+   * {@code true} if signature help was already showing when it was triggered.
+   * <p>
+   * Retriggers occur when the signature help is already active and can be caused by actions such as
+   * typing a trigger character, a cursor move, or document content changes.
+   */
+  @Pure
+  public boolean isRetrigger() {
+    return this.isRetrigger;
+  }
+  
+  /**
+   * {@code true} if signature help was already showing when it was triggered.
+   * <p>
+   * Retriggers occur when the signature help is already active and can be caused by actions such as
+   * typing a trigger character, a cursor move, or document content changes.
+   */
+  public void setIsRetrigger(final boolean isRetrigger) {
+    this.isRetrigger = isRetrigger;
+  }
+  
+  /**
+   * The currently active {@link SignatureHelp}.
+   * <p>
+   * The `activeSignatureHelp` has its {@link SignatureHelp#activeSignature} field updated based on
+   * the user navigating through available signatures.
+   */
+  @Pure
+  public SignatureHelp getActiveSignatureHelp() {
+    return this.activeSignatureHelp;
+  }
+  
+  /**
+   * The currently active {@link SignatureHelp}.
+   * <p>
+   * The `activeSignatureHelp` has its {@link SignatureHelp#activeSignature} field updated based on
+   * the user navigating through available signatures.
+   */
+  public void setActiveSignatureHelp(final SignatureHelp activeSignatureHelp) {
+    this.activeSignatureHelp = activeSignatureHelp;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("triggerKind", this.triggerKind);
+    b.add("triggerCharacter", this.triggerCharacter);
+    b.add("isRetrigger", this.isRetrigger);
+    b.add("activeSignatureHelp", this.activeSignatureHelp);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SignatureHelpContext other = (SignatureHelpContext) obj;
+    if (this.triggerKind == null) {
+      if (other.triggerKind != null)
+        return false;
+    } else if (!this.triggerKind.equals(other.triggerKind))
+      return false;
+    if (this.triggerCharacter == null) {
+      if (other.triggerCharacter != null)
+        return false;
+    } else if (!this.triggerCharacter.equals(other.triggerCharacter))
+      return false;
+    if (other.isRetrigger != this.isRetrigger)
+      return false;
+    if (this.activeSignatureHelp == null) {
+      if (other.activeSignatureHelp != null)
+        return false;
+    } else if (!this.activeSignatureHelp.equals(other.activeSignatureHelp))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.triggerKind== null) ? 0 : this.triggerKind.hashCode());
+    result = prime * result + ((this.triggerCharacter== null) ? 0 : this.triggerCharacter.hashCode());
+    result = prime * result + (this.isRetrigger ? 1231 : 1237);
+    return prime * result + ((this.activeSignatureHelp== null) ? 0 : this.activeSignatureHelp.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SignatureHelpOptions.java b/java/org/eclipse/lsp4j/SignatureHelpOptions.java
new file mode 100644
index 0000000..5db394e
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SignatureHelpOptions.java
@@ -0,0 +1,134 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.AbstractWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Signature help options.
+ */
+@SuppressWarnings("all")
+public class SignatureHelpOptions extends AbstractWorkDoneProgressOptions {
+  /**
+   * The characters that trigger signature help automatically.
+   */
+  private List<String> triggerCharacters;
+  
+  /**
+   * List of characters that re-trigger signature help.
+   * <p>
+   * These trigger characters are only active when signature help is already showing. All trigger characters
+   * are also counted as re-trigger characters.
+   * <p>
+   * Since 3.15.0
+   */
+  private List<String> retriggerCharacters;
+  
+  public SignatureHelpOptions() {
+  }
+  
+  public SignatureHelpOptions(final List<String> triggerCharacters) {
+    this.triggerCharacters = triggerCharacters;
+  }
+  
+  public SignatureHelpOptions(final List<String> triggerCharacters, final List<String> retriggerCharacters) {
+    this(triggerCharacters);
+    this.retriggerCharacters = retriggerCharacters;
+  }
+  
+  /**
+   * The characters that trigger signature help automatically.
+   */
+  @Pure
+  public List<String> getTriggerCharacters() {
+    return this.triggerCharacters;
+  }
+  
+  /**
+   * The characters that trigger signature help automatically.
+   */
+  public void setTriggerCharacters(final List<String> triggerCharacters) {
+    this.triggerCharacters = triggerCharacters;
+  }
+  
+  /**
+   * List of characters that re-trigger signature help.
+   * <p>
+   * These trigger characters are only active when signature help is already showing. All trigger characters
+   * are also counted as re-trigger characters.
+   * <p>
+   * Since 3.15.0
+   */
+  @Pure
+  public List<String> getRetriggerCharacters() {
+    return this.retriggerCharacters;
+  }
+  
+  /**
+   * List of characters that re-trigger signature help.
+   * <p>
+   * These trigger characters are only active when signature help is already showing. All trigger characters
+   * are also counted as re-trigger characters.
+   * <p>
+   * Since 3.15.0
+   */
+  public void setRetriggerCharacters(final List<String> retriggerCharacters) {
+    this.retriggerCharacters = retriggerCharacters;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("triggerCharacters", this.triggerCharacters);
+    b.add("retriggerCharacters", this.retriggerCharacters);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    SignatureHelpOptions other = (SignatureHelpOptions) obj;
+    if (this.triggerCharacters == null) {
+      if (other.triggerCharacters != null)
+        return false;
+    } else if (!this.triggerCharacters.equals(other.triggerCharacters))
+      return false;
+    if (this.retriggerCharacters == null) {
+      if (other.retriggerCharacters != null)
+        return false;
+    } else if (!this.retriggerCharacters.equals(other.retriggerCharacters))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.triggerCharacters== null) ? 0 : this.triggerCharacters.hashCode());
+    return prime * result + ((this.retriggerCharacters== null) ? 0 : this.retriggerCharacters.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SignatureHelpParams.java b/java/org/eclipse/lsp4j/SignatureHelpParams.java
new file mode 100644
index 0000000..1bc3774
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SignatureHelpParams.java
@@ -0,0 +1,105 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.Position;
+import org.eclipse.lsp4j.SignatureHelpContext;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.TextDocumentPositionAndWorkDoneProgressParams;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The signature help request is sent from the client to the server to request signature information at a given cursor position.
+ */
+@SuppressWarnings("all")
+public class SignatureHelpParams extends TextDocumentPositionAndWorkDoneProgressParams {
+  /**
+   * The signature help context. This is only available if the client specifies
+   * to send this using the client capability {@link SignatureHelpCapabilities#contextSupport} as true.
+   * <p>
+   * Since 3.15.0
+   */
+  private SignatureHelpContext context;
+  
+  public SignatureHelpParams() {
+  }
+  
+  public SignatureHelpParams(@NonNull final TextDocumentIdentifier textDocument, @NonNull final Position position) {
+    super(textDocument, position);
+  }
+  
+  public SignatureHelpParams(@NonNull final TextDocumentIdentifier textDocument, @NonNull final Position position, final SignatureHelpContext context) {
+    this(textDocument, position);
+    this.context = context;
+  }
+  
+  /**
+   * The signature help context. This is only available if the client specifies
+   * to send this using the client capability {@link SignatureHelpCapabilities#contextSupport} as true.
+   * <p>
+   * Since 3.15.0
+   */
+  @Pure
+  public SignatureHelpContext getContext() {
+    return this.context;
+  }
+  
+  /**
+   * The signature help context. This is only available if the client specifies
+   * to send this using the client capability {@link SignatureHelpCapabilities#contextSupport} as true.
+   * <p>
+   * Since 3.15.0
+   */
+  public void setContext(final SignatureHelpContext context) {
+    this.context = context;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("context", this.context);
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("textDocument", getTextDocument());
+    b.add("uri", getUri());
+    b.add("position", getPosition());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    SignatureHelpParams other = (SignatureHelpParams) obj;
+    if (this.context == null) {
+      if (other.context != null)
+        return false;
+    } else if (!this.context.equals(other.context))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.context== null) ? 0 : this.context.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SignatureHelpRegistrationOptions.java b/java/org/eclipse/lsp4j/SignatureHelpRegistrationOptions.java
new file mode 100644
index 0000000..53cb9a6
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SignatureHelpRegistrationOptions.java
@@ -0,0 +1,132 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.AbstractTextDocumentRegistrationAndWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class SignatureHelpRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+  /**
+   * The characters that trigger signature help automatically.
+   */
+  private List<String> triggerCharacters;
+  
+  /**
+   * List of characters that re-trigger signature help.
+   * <p>
+   * These trigger characters are only active when signature help is already showing. All trigger characters
+   * are also counted as re-trigger characters.
+   * <p>
+   * Since 3.15.0
+   */
+  private List<String> retriggerCharacters;
+  
+  public SignatureHelpRegistrationOptions() {
+  }
+  
+  public SignatureHelpRegistrationOptions(final List<String> triggerCharacters) {
+    this.triggerCharacters = triggerCharacters;
+  }
+  
+  public SignatureHelpRegistrationOptions(final List<String> triggerCharacters, final List<String> retriggerCharacters) {
+    this(triggerCharacters);
+    this.retriggerCharacters = retriggerCharacters;
+  }
+  
+  /**
+   * The characters that trigger signature help automatically.
+   */
+  @Pure
+  public List<String> getTriggerCharacters() {
+    return this.triggerCharacters;
+  }
+  
+  /**
+   * The characters that trigger signature help automatically.
+   */
+  public void setTriggerCharacters(final List<String> triggerCharacters) {
+    this.triggerCharacters = triggerCharacters;
+  }
+  
+  /**
+   * List of characters that re-trigger signature help.
+   * <p>
+   * These trigger characters are only active when signature help is already showing. All trigger characters
+   * are also counted as re-trigger characters.
+   * <p>
+   * Since 3.15.0
+   */
+  @Pure
+  public List<String> getRetriggerCharacters() {
+    return this.retriggerCharacters;
+  }
+  
+  /**
+   * List of characters that re-trigger signature help.
+   * <p>
+   * These trigger characters are only active when signature help is already showing. All trigger characters
+   * are also counted as re-trigger characters.
+   * <p>
+   * Since 3.15.0
+   */
+  public void setRetriggerCharacters(final List<String> retriggerCharacters) {
+    this.retriggerCharacters = retriggerCharacters;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("triggerCharacters", this.triggerCharacters);
+    b.add("retriggerCharacters", this.retriggerCharacters);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    SignatureHelpRegistrationOptions other = (SignatureHelpRegistrationOptions) obj;
+    if (this.triggerCharacters == null) {
+      if (other.triggerCharacters != null)
+        return false;
+    } else if (!this.triggerCharacters.equals(other.triggerCharacters))
+      return false;
+    if (this.retriggerCharacters == null) {
+      if (other.retriggerCharacters != null)
+        return false;
+    } else if (!this.retriggerCharacters.equals(other.retriggerCharacters))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.triggerCharacters== null) ? 0 : this.triggerCharacters.hashCode());
+    return prime * result + ((this.retriggerCharacters== null) ? 0 : this.retriggerCharacters.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SignatureHelpTriggerKind.java b/java/org/eclipse/lsp4j/SignatureHelpTriggerKind.java
new file mode 100644
index 0000000..d036189
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SignatureHelpTriggerKind.java
@@ -0,0 +1,53 @@
+/******************************************************************************
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j;
+
+/**
+ * How a signature help was triggered.
+ * 
+ * Since 3.15.0
+ */
+public enum SignatureHelpTriggerKind {
+	
+	/**
+	 * Signature help was invoked manually by the user or by a command.
+	 */
+	Invoked(1),
+	
+	/**
+	 * Signature help was triggered by a trigger character.
+	 */
+	TriggerCharacter(2),
+	
+	/**
+	 * Signature help was triggered by the cursor moving or by the document content changing.
+	 */
+	ContentChange(3);
+	
+	private final int value;
+	
+	SignatureHelpTriggerKind(int value) {
+		this.value = value;
+	}
+	
+	public int getValue() {
+		return value;
+	}
+	
+	public static SignatureHelpTriggerKind forValue(int value) {
+		SignatureHelpTriggerKind[] allValues = SignatureHelpTriggerKind.values();
+		if (value < 1 || value > allValues.length)
+			throw new IllegalArgumentException("Illegal enum value: " + value);
+		return allValues[value - 1];
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/SignatureInformation.java b/java/org/eclipse/lsp4j/SignatureInformation.java
new file mode 100644
index 0000000..c5e3c19
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SignatureInformation.java
@@ -0,0 +1,212 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.MarkupContent;
+import org.eclipse.lsp4j.ParameterInformation;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Represents the signature of something callable. A signature can have a label, like a function-name, a doc-comment, and
+ * a set of parameters.
+ */
+@SuppressWarnings("all")
+public class SignatureInformation {
+  /**
+   * The label of this signature. Will be shown in the UI.
+   */
+  @NonNull
+  private String label;
+  
+  /**
+   * The human-readable doc-comment of this signature. Will be shown in the UI but can be omitted.
+   */
+  private Either<String, MarkupContent> documentation;
+  
+  /**
+   * The parameters of this signature.
+   */
+  private List<ParameterInformation> parameters;
+  
+  /**
+   * The index of the active parameter.
+   * <p>
+   * If provided, this is used in place of {@link SignatureHelp#activeParameter}.
+   * <p>
+   * Since 3.16.0
+   */
+  private Integer activeParameter;
+  
+  public SignatureInformation() {
+  }
+  
+  public SignatureInformation(@NonNull final String label) {
+    this.label = Preconditions.<String>checkNotNull(label, "label");
+  }
+  
+  public SignatureInformation(@NonNull final String label, final String documentation, final List<ParameterInformation> parameters) {
+    this(label);
+    this.setDocumentation(documentation);
+    this.parameters = parameters;
+  }
+  
+  public SignatureInformation(@NonNull final String label, final MarkupContent documentation, final List<ParameterInformation> parameters) {
+    this(label);
+    this.setDocumentation(documentation);
+    this.parameters = parameters;
+  }
+  
+  /**
+   * The label of this signature. Will be shown in the UI.
+   */
+  @Pure
+  @NonNull
+  public String getLabel() {
+    return this.label;
+  }
+  
+  /**
+   * The label of this signature. Will be shown in the UI.
+   */
+  public void setLabel(@NonNull final String label) {
+    this.label = Preconditions.checkNotNull(label, "label");
+  }
+  
+  /**
+   * The human-readable doc-comment of this signature. Will be shown in the UI but can be omitted.
+   */
+  @Pure
+  public Either<String, MarkupContent> getDocumentation() {
+    return this.documentation;
+  }
+  
+  /**
+   * The human-readable doc-comment of this signature. Will be shown in the UI but can be omitted.
+   */
+  public void setDocumentation(final Either<String, MarkupContent> documentation) {
+    this.documentation = documentation;
+  }
+  
+  public void setDocumentation(final String documentation) {
+    if (documentation == null) {
+      this.documentation = null;
+      return;
+    }
+    this.documentation = Either.forLeft(documentation);
+  }
+  
+  public void setDocumentation(final MarkupContent documentation) {
+    if (documentation == null) {
+      this.documentation = null;
+      return;
+    }
+    this.documentation = Either.forRight(documentation);
+  }
+  
+  /**
+   * The parameters of this signature.
+   */
+  @Pure
+  public List<ParameterInformation> getParameters() {
+    return this.parameters;
+  }
+  
+  /**
+   * The parameters of this signature.
+   */
+  public void setParameters(final List<ParameterInformation> parameters) {
+    this.parameters = parameters;
+  }
+  
+  /**
+   * The index of the active parameter.
+   * <p>
+   * If provided, this is used in place of {@link SignatureHelp#activeParameter}.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public Integer getActiveParameter() {
+    return this.activeParameter;
+  }
+  
+  /**
+   * The index of the active parameter.
+   * <p>
+   * If provided, this is used in place of {@link SignatureHelp#activeParameter}.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setActiveParameter(final Integer activeParameter) {
+    this.activeParameter = activeParameter;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("label", this.label);
+    b.add("documentation", this.documentation);
+    b.add("parameters", this.parameters);
+    b.add("activeParameter", this.activeParameter);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SignatureInformation other = (SignatureInformation) obj;
+    if (this.label == null) {
+      if (other.label != null)
+        return false;
+    } else if (!this.label.equals(other.label))
+      return false;
+    if (this.documentation == null) {
+      if (other.documentation != null)
+        return false;
+    } else if (!this.documentation.equals(other.documentation))
+      return false;
+    if (this.parameters == null) {
+      if (other.parameters != null)
+        return false;
+    } else if (!this.parameters.equals(other.parameters))
+      return false;
+    if (this.activeParameter == null) {
+      if (other.activeParameter != null)
+        return false;
+    } else if (!this.activeParameter.equals(other.activeParameter))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.label== null) ? 0 : this.label.hashCode());
+    result = prime * result + ((this.documentation== null) ? 0 : this.documentation.hashCode());
+    result = prime * result + ((this.parameters== null) ? 0 : this.parameters.hashCode());
+    return prime * result + ((this.activeParameter== null) ? 0 : this.activeParameter.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SignatureInformationCapabilities.java b/java/org/eclipse/lsp4j/SignatureInformationCapabilities.java
new file mode 100644
index 0000000..813b426
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SignatureInformationCapabilities.java
@@ -0,0 +1,153 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.ParameterInformationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The client supports the following {@link SignatureInformation} specific properties.
+ */
+@SuppressWarnings("all")
+public class SignatureInformationCapabilities {
+  /**
+   * Client supports the following content formats for the documentation
+   * property. The order describes the preferred format of the client.
+   * <p>
+   * See {@link MarkupKind} for allowed values.
+   */
+  private List<String> documentationFormat;
+  
+  /**
+   * Client capabilities specific to parameter information.
+   */
+  private ParameterInformationCapabilities parameterInformation;
+  
+  /**
+   * The client supports the {@link SignatureInformation#activeParameter} property.
+   * <p>
+   * Since 3.16.0
+   */
+  private Boolean activeParameterSupport;
+  
+  public SignatureInformationCapabilities() {
+  }
+  
+  public SignatureInformationCapabilities(final List<String> documentationFormat) {
+    this.documentationFormat = documentationFormat;
+  }
+  
+  /**
+   * Client supports the following content formats for the documentation
+   * property. The order describes the preferred format of the client.
+   * <p>
+   * See {@link MarkupKind} for allowed values.
+   */
+  @Pure
+  public List<String> getDocumentationFormat() {
+    return this.documentationFormat;
+  }
+  
+  /**
+   * Client supports the following content formats for the documentation
+   * property. The order describes the preferred format of the client.
+   * <p>
+   * See {@link MarkupKind} for allowed values.
+   */
+  public void setDocumentationFormat(final List<String> documentationFormat) {
+    this.documentationFormat = documentationFormat;
+  }
+  
+  /**
+   * Client capabilities specific to parameter information.
+   */
+  @Pure
+  public ParameterInformationCapabilities getParameterInformation() {
+    return this.parameterInformation;
+  }
+  
+  /**
+   * Client capabilities specific to parameter information.
+   */
+  public void setParameterInformation(final ParameterInformationCapabilities parameterInformation) {
+    this.parameterInformation = parameterInformation;
+  }
+  
+  /**
+   * The client supports the {@link SignatureInformation#activeParameter} property.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public Boolean getActiveParameterSupport() {
+    return this.activeParameterSupport;
+  }
+  
+  /**
+   * The client supports the {@link SignatureInformation#activeParameter} property.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setActiveParameterSupport(final Boolean activeParameterSupport) {
+    this.activeParameterSupport = activeParameterSupport;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("documentationFormat", this.documentationFormat);
+    b.add("parameterInformation", this.parameterInformation);
+    b.add("activeParameterSupport", this.activeParameterSupport);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SignatureInformationCapabilities other = (SignatureInformationCapabilities) obj;
+    if (this.documentationFormat == null) {
+      if (other.documentationFormat != null)
+        return false;
+    } else if (!this.documentationFormat.equals(other.documentationFormat))
+      return false;
+    if (this.parameterInformation == null) {
+      if (other.parameterInformation != null)
+        return false;
+    } else if (!this.parameterInformation.equals(other.parameterInformation))
+      return false;
+    if (this.activeParameterSupport == null) {
+      if (other.activeParameterSupport != null)
+        return false;
+    } else if (!this.activeParameterSupport.equals(other.activeParameterSupport))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.documentationFormat== null) ? 0 : this.documentationFormat.hashCode());
+    result = prime * result + ((this.parameterInformation== null) ? 0 : this.parameterInformation.hashCode());
+    return prime * result + ((this.activeParameterSupport== null) ? 0 : this.activeParameterSupport.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/StaticRegistrationOptions.java b/java/org/eclipse/lsp4j/StaticRegistrationOptions.java
new file mode 100644
index 0000000..5a66897
--- /dev/null
+++ b/java/org/eclipse/lsp4j/StaticRegistrationOptions.java
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.TextDocumentRegistrationOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Static registration options to be returned in the initialize request.
+ */
+@SuppressWarnings("all")
+public class StaticRegistrationOptions extends TextDocumentRegistrationOptions {
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  private String id;
+  
+  public StaticRegistrationOptions() {
+  }
+  
+  public StaticRegistrationOptions(final String id) {
+    this.id = id;
+  }
+  
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  @Pure
+  public String getId() {
+    return this.id;
+  }
+  
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  public void setId(final String id) {
+    this.id = id;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("id", this.id);
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    StaticRegistrationOptions other = (StaticRegistrationOptions) obj;
+    if (this.id == null) {
+      if (other.id != null)
+        return false;
+    } else if (!this.id.equals(other.id))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.id== null) ? 0 : this.id.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SymbolCapabilities.java b/java/org/eclipse/lsp4j/SymbolCapabilities.java
new file mode 100644
index 0000000..0adfdbf
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SymbolCapabilities.java
@@ -0,0 +1,134 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.lsp4j.SymbolKindCapabilities;
+import org.eclipse.lsp4j.SymbolTagSupportCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the `workspace/symbol` request.
+ * Referred to in the spec as WorkspaceSymbolClientCapabilities.
+ */
+@SuppressWarnings("all")
+public class SymbolCapabilities extends DynamicRegistrationCapabilities {
+  /**
+   * Specific capabilities for the {@link SymbolKind} in the `workspace/symbol` request.
+   */
+  private SymbolKindCapabilities symbolKind;
+  
+  /**
+   * The client supports tags on {@link SymbolInformation}.
+   * Clients supporting tags have to handle unknown tags gracefully.
+   * <p>
+   * Since 3.16.0
+   */
+  private SymbolTagSupportCapabilities tagSupport;
+  
+  public SymbolCapabilities() {
+  }
+  
+  public SymbolCapabilities(final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+  }
+  
+  public SymbolCapabilities(final SymbolKindCapabilities symbolKind) {
+    this.symbolKind = symbolKind;
+  }
+  
+  public SymbolCapabilities(final SymbolKindCapabilities symbolKind, final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+    this.symbolKind = symbolKind;
+  }
+  
+  /**
+   * Specific capabilities for the {@link SymbolKind} in the `workspace/symbol` request.
+   */
+  @Pure
+  public SymbolKindCapabilities getSymbolKind() {
+    return this.symbolKind;
+  }
+  
+  /**
+   * Specific capabilities for the {@link SymbolKind} in the `workspace/symbol` request.
+   */
+  public void setSymbolKind(final SymbolKindCapabilities symbolKind) {
+    this.symbolKind = symbolKind;
+  }
+  
+  /**
+   * The client supports tags on {@link SymbolInformation}.
+   * Clients supporting tags have to handle unknown tags gracefully.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public SymbolTagSupportCapabilities getTagSupport() {
+    return this.tagSupport;
+  }
+  
+  /**
+   * The client supports tags on {@link SymbolInformation}.
+   * Clients supporting tags have to handle unknown tags gracefully.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setTagSupport(final SymbolTagSupportCapabilities tagSupport) {
+    this.tagSupport = tagSupport;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("symbolKind", this.symbolKind);
+    b.add("tagSupport", this.tagSupport);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    SymbolCapabilities other = (SymbolCapabilities) obj;
+    if (this.symbolKind == null) {
+      if (other.symbolKind != null)
+        return false;
+    } else if (!this.symbolKind.equals(other.symbolKind))
+      return false;
+    if (this.tagSupport == null) {
+      if (other.tagSupport != null)
+        return false;
+    } else if (!this.tagSupport.equals(other.tagSupport))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.symbolKind== null) ? 0 : this.symbolKind.hashCode());
+    return prime * result + ((this.tagSupport== null) ? 0 : this.tagSupport.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SymbolInformation.java b/java/org/eclipse/lsp4j/SymbolInformation.java
new file mode 100644
index 0000000..e96989c
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SymbolInformation.java
@@ -0,0 +1,287 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import com.google.gson.annotations.JsonAdapter;
+import java.util.List;
+import org.eclipse.lsp4j.Location;
+import org.eclipse.lsp4j.SymbolKind;
+import org.eclipse.lsp4j.SymbolTag;
+import org.eclipse.lsp4j.adapters.SymbolInformationTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Represents information about programming constructs like variables, classes, interfaces etc.
+ */
+@JsonAdapter(SymbolInformationTypeAdapter.Factory.class)
+@SuppressWarnings("all")
+public class SymbolInformation {
+  /**
+   * The name of this symbol.
+   */
+  @NonNull
+  private String name;
+  
+  /**
+   * The kind of this symbol.
+   */
+  @NonNull
+  private SymbolKind kind;
+  
+  /**
+   * Tags for this symbol.
+   * <p>
+   * Since 3.16.0
+   */
+  private List<SymbolTag> tags;
+  
+  /**
+   * Indicates if this symbol is deprecated.
+   * 
+   * @deprecated Use {@link #tags} instead if supported.
+   */
+  @Deprecated
+  private Boolean deprecated;
+  
+  /**
+   * The location of this symbol. The location's range is used by a tool
+   * to reveal the location in the editor. If the symbol is selected in the
+   * tool the range's start information is used to position the cursor. So
+   * the range usually spans more then the actual symbol's name and does
+   * normally include things like visibility modifiers.
+   * <p>
+   * The range doesn't have to denote a node range in the sense of a abstract
+   * syntax tree. It can therefore not be used to re-construct a hierarchy of
+   * the symbols.
+   */
+  @NonNull
+  private Location location;
+  
+  /**
+   * The name of the symbol containing this symbol. This information is for
+   * user interface purposes (e.g. to render a qualifier in the user interface
+   * if necessary). It can't be used to re-infer a hierarchy for the document
+   * symbols.
+   */
+  private String containerName;
+  
+  public SymbolInformation() {
+  }
+  
+  public SymbolInformation(@NonNull final String name, @NonNull final SymbolKind kind, @NonNull final Location location) {
+    this.name = Preconditions.<String>checkNotNull(name, "name");
+    this.kind = Preconditions.<SymbolKind>checkNotNull(kind, "kind");
+    this.location = Preconditions.<Location>checkNotNull(location, "location");
+  }
+  
+  public SymbolInformation(@NonNull final String name, @NonNull final SymbolKind kind, @NonNull final Location location, final String containerName) {
+    this(name, kind, location);
+    this.containerName = containerName;
+  }
+  
+  /**
+   * The name of this symbol.
+   */
+  @Pure
+  @NonNull
+  public String getName() {
+    return this.name;
+  }
+  
+  /**
+   * The name of this symbol.
+   */
+  public void setName(@NonNull final String name) {
+    this.name = Preconditions.checkNotNull(name, "name");
+  }
+  
+  /**
+   * The kind of this symbol.
+   */
+  @Pure
+  @NonNull
+  public SymbolKind getKind() {
+    return this.kind;
+  }
+  
+  /**
+   * The kind of this symbol.
+   */
+  public void setKind(@NonNull final SymbolKind kind) {
+    this.kind = Preconditions.checkNotNull(kind, "kind");
+  }
+  
+  /**
+   * Tags for this symbol.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public List<SymbolTag> getTags() {
+    return this.tags;
+  }
+  
+  /**
+   * Tags for this symbol.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setTags(final List<SymbolTag> tags) {
+    this.tags = tags;
+  }
+  
+  /**
+   * Indicates if this symbol is deprecated.
+   * 
+   * @deprecated Use {@link #tags} instead if supported.
+   */
+  @Pure
+  @Deprecated
+  public Boolean getDeprecated() {
+    return this.deprecated;
+  }
+  
+  /**
+   * Indicates if this symbol is deprecated.
+   * 
+   * @deprecated Use {@link #tags} instead if supported.
+   */
+  @Deprecated
+  public void setDeprecated(final Boolean deprecated) {
+    this.deprecated = deprecated;
+  }
+  
+  /**
+   * The location of this symbol. The location's range is used by a tool
+   * to reveal the location in the editor. If the symbol is selected in the
+   * tool the range's start information is used to position the cursor. So
+   * the range usually spans more then the actual symbol's name and does
+   * normally include things like visibility modifiers.
+   * <p>
+   * The range doesn't have to denote a node range in the sense of a abstract
+   * syntax tree. It can therefore not be used to re-construct a hierarchy of
+   * the symbols.
+   */
+  @Pure
+  @NonNull
+  public Location getLocation() {
+    return this.location;
+  }
+  
+  /**
+   * The location of this symbol. The location's range is used by a tool
+   * to reveal the location in the editor. If the symbol is selected in the
+   * tool the range's start information is used to position the cursor. So
+   * the range usually spans more then the actual symbol's name and does
+   * normally include things like visibility modifiers.
+   * <p>
+   * The range doesn't have to denote a node range in the sense of a abstract
+   * syntax tree. It can therefore not be used to re-construct a hierarchy of
+   * the symbols.
+   */
+  public void setLocation(@NonNull final Location location) {
+    this.location = Preconditions.checkNotNull(location, "location");
+  }
+  
+  /**
+   * The name of the symbol containing this symbol. This information is for
+   * user interface purposes (e.g. to render a qualifier in the user interface
+   * if necessary). It can't be used to re-infer a hierarchy for the document
+   * symbols.
+   */
+  @Pure
+  public String getContainerName() {
+    return this.containerName;
+  }
+  
+  /**
+   * The name of the symbol containing this symbol. This information is for
+   * user interface purposes (e.g. to render a qualifier in the user interface
+   * if necessary). It can't be used to re-infer a hierarchy for the document
+   * symbols.
+   */
+  public void setContainerName(final String containerName) {
+    this.containerName = containerName;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("name", this.name);
+    b.add("kind", this.kind);
+    b.add("tags", this.tags);
+    b.add("deprecated", this.deprecated);
+    b.add("location", this.location);
+    b.add("containerName", this.containerName);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SymbolInformation other = (SymbolInformation) obj;
+    if (this.name == null) {
+      if (other.name != null)
+        return false;
+    } else if (!this.name.equals(other.name))
+      return false;
+    if (this.kind == null) {
+      if (other.kind != null)
+        return false;
+    } else if (!this.kind.equals(other.kind))
+      return false;
+    if (this.tags == null) {
+      if (other.tags != null)
+        return false;
+    } else if (!this.tags.equals(other.tags))
+      return false;
+    if (this.deprecated == null) {
+      if (other.deprecated != null)
+        return false;
+    } else if (!this.deprecated.equals(other.deprecated))
+      return false;
+    if (this.location == null) {
+      if (other.location != null)
+        return false;
+    } else if (!this.location.equals(other.location))
+      return false;
+    if (this.containerName == null) {
+      if (other.containerName != null)
+        return false;
+    } else if (!this.containerName.equals(other.containerName))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.name== null) ? 0 : this.name.hashCode());
+    result = prime * result + ((this.kind== null) ? 0 : this.kind.hashCode());
+    result = prime * result + ((this.tags== null) ? 0 : this.tags.hashCode());
+    result = prime * result + ((this.deprecated== null) ? 0 : this.deprecated.hashCode());
+    result = prime * result + ((this.location== null) ? 0 : this.location.hashCode());
+    return prime * result + ((this.containerName== null) ? 0 : this.containerName.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SymbolKind.java b/java/org/eclipse/lsp4j/SymbolKind.java
new file mode 100644
index 0000000..343287f
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SymbolKind.java
@@ -0,0 +1,85 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j;
+
+public enum SymbolKind {
+	
+	File(1),
+	
+	Module(2),
+	
+	Namespace(3),
+	
+	Package(4),
+	
+	Class(5),
+	
+	Method(6),
+	
+	Property(7),
+	
+	Field(8),
+	
+	Constructor(9),
+	
+	Enum(10),
+	
+	Interface(11),
+	
+	Function(12),
+	
+	Variable(13),
+	
+	Constant(14),
+	
+	String(15),
+	
+	Number(16),
+	
+	Boolean(17),
+	
+	Array(18),
+	
+	Object(19),
+	
+	Key(20),
+	
+	Null(21),
+	
+	EnumMember(22),
+	
+	Struct(23),
+	
+	Event(24),
+	
+	Operator(25),
+	
+	TypeParameter(26);
+	
+	private final int value;
+	
+	SymbolKind(int value) {
+		this.value = value;
+	}
+	
+	public int getValue() {
+		return value;
+	}
+	
+	public static SymbolKind forValue(int value) {
+		SymbolKind[] allValues = SymbolKind.values();
+		if (value < 1 || value > allValues.length)
+			throw new IllegalArgumentException("Illegal enum value: " + value);
+		return allValues[value - 1];
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/SymbolKindCapabilities.java b/java/org/eclipse/lsp4j/SymbolKindCapabilities.java
new file mode 100644
index 0000000..91f5eef
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SymbolKindCapabilities.java
@@ -0,0 +1,103 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.SymbolKind;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Specific capabilities for the {@link SymbolKind}.
+ */
+@SuppressWarnings("all")
+public class SymbolKindCapabilities {
+  /**
+   * The symbol kind values the client supports. When this
+   * property exists the client also guarantees that it will
+   * handle values outside its set gracefully and falls back
+   * to a default value when unknown.
+   * <p>
+   * If this property is not present the client only supports
+   * the symbol kinds from {@link SymbolKind#File} to
+   * {@link SymbolKind#Array} as defined in the initial version of the protocol.
+   */
+  private List<SymbolKind> valueSet;
+  
+  public SymbolKindCapabilities() {
+  }
+  
+  public SymbolKindCapabilities(final List<SymbolKind> valueSet) {
+    this.valueSet = valueSet;
+  }
+  
+  /**
+   * The symbol kind values the client supports. When this
+   * property exists the client also guarantees that it will
+   * handle values outside its set gracefully and falls back
+   * to a default value when unknown.
+   * <p>
+   * If this property is not present the client only supports
+   * the symbol kinds from {@link SymbolKind#File} to
+   * {@link SymbolKind#Array} as defined in the initial version of the protocol.
+   */
+  @Pure
+  public List<SymbolKind> getValueSet() {
+    return this.valueSet;
+  }
+  
+  /**
+   * The symbol kind values the client supports. When this
+   * property exists the client also guarantees that it will
+   * handle values outside its set gracefully and falls back
+   * to a default value when unknown.
+   * <p>
+   * If this property is not present the client only supports
+   * the symbol kinds from {@link SymbolKind#File} to
+   * {@link SymbolKind#Array} as defined in the initial version of the protocol.
+   */
+  public void setValueSet(final List<SymbolKind> valueSet) {
+    this.valueSet = valueSet;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("valueSet", this.valueSet);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SymbolKindCapabilities other = (SymbolKindCapabilities) obj;
+    if (this.valueSet == null) {
+      if (other.valueSet != null)
+        return false;
+    } else if (!this.valueSet.equals(other.valueSet))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.valueSet== null) ? 0 : this.valueSet.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SymbolTag.java b/java/org/eclipse/lsp4j/SymbolTag.java
new file mode 100644
index 0000000..9a87c55
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SymbolTag.java
@@ -0,0 +1,43 @@
+/******************************************************************************
+ * Copyright (c) 2019 Microsoft Corporation and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+
+package org.eclipse.lsp4j;
+
+/**
+ * Symbol tags are extra annotations that tweak the rendering of a symbol.
+ * 
+ * Since 3.16
+ */
+public enum SymbolTag {
+
+	/**
+	 * Render a symbol as obsolete, usually using a strike-out.
+	 */
+	Deprecated(1);
+
+	private final int value;
+	
+	SymbolTag(int value) {
+		this.value = value;
+	}
+	
+	public int getValue() {
+		return value;
+	}
+
+	public static SymbolTag forValue(int value) {
+		SymbolTag[] allValues = SymbolTag.values();
+		if (value < 1 || value > allValues.length)
+			throw new IllegalArgumentException("Illegal enum value: " + value);
+		return allValues[value - 1];
+	}
+}
\ No newline at end of file
diff --git a/java/org/eclipse/lsp4j/SymbolTagSupportCapabilities.java b/java/org/eclipse/lsp4j/SymbolTagSupportCapabilities.java
new file mode 100644
index 0000000..d7b99f0
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SymbolTagSupportCapabilities.java
@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.lsp4j.SymbolTag;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Specific capabilities for the {@link SymbolTag}.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class SymbolTagSupportCapabilities {
+  /**
+   * The tags supported by the client.
+   */
+  @NonNull
+  private List<SymbolTag> valueSet;
+  
+  public SymbolTagSupportCapabilities() {
+    ArrayList<SymbolTag> _arrayList = new ArrayList<SymbolTag>();
+    this.valueSet = _arrayList;
+  }
+  
+  public SymbolTagSupportCapabilities(@NonNull final List<SymbolTag> valueSet) {
+    this.valueSet = Preconditions.<List<SymbolTag>>checkNotNull(valueSet, "valueSet");
+  }
+  
+  /**
+   * The tags supported by the client.
+   */
+  @Pure
+  @NonNull
+  public List<SymbolTag> getValueSet() {
+    return this.valueSet;
+  }
+  
+  /**
+   * The tags supported by the client.
+   */
+  public void setValueSet(@NonNull final List<SymbolTag> valueSet) {
+    this.valueSet = Preconditions.checkNotNull(valueSet, "valueSet");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("valueSet", this.valueSet);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SymbolTagSupportCapabilities other = (SymbolTagSupportCapabilities) obj;
+    if (this.valueSet == null) {
+      if (other.valueSet != null)
+        return false;
+    } else if (!this.valueSet.equals(other.valueSet))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.valueSet== null) ? 0 : this.valueSet.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/SynchronizationCapabilities.java b/java/org/eclipse/lsp4j/SynchronizationCapabilities.java
new file mode 100644
index 0000000..e3bef92
--- /dev/null
+++ b/java/org/eclipse/lsp4j/SynchronizationCapabilities.java
@@ -0,0 +1,152 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class SynchronizationCapabilities extends DynamicRegistrationCapabilities {
+  /**
+   * The client supports sending will save notifications.
+   */
+  private Boolean willSave;
+  
+  /**
+   * The client supports sending a will save request and
+   * waits for a response providing text edits which will
+   * be applied to the document before it is saved.
+   */
+  private Boolean willSaveWaitUntil;
+  
+  /**
+   * The client supports did save notifications.
+   */
+  private Boolean didSave;
+  
+  public SynchronizationCapabilities() {
+  }
+  
+  public SynchronizationCapabilities(final Boolean willSave, final Boolean willSaveWaitUntil, final Boolean didSave) {
+    this.willSave = willSave;
+    this.willSaveWaitUntil = willSaveWaitUntil;
+    this.didSave = didSave;
+  }
+  
+  public SynchronizationCapabilities(final Boolean willSave, final Boolean willSaveWaitUntil, final Boolean didSave, final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+    this.willSave = willSave;
+    this.willSaveWaitUntil = willSaveWaitUntil;
+    this.didSave = didSave;
+  }
+  
+  /**
+   * The client supports sending will save notifications.
+   */
+  @Pure
+  public Boolean getWillSave() {
+    return this.willSave;
+  }
+  
+  /**
+   * The client supports sending will save notifications.
+   */
+  public void setWillSave(final Boolean willSave) {
+    this.willSave = willSave;
+  }
+  
+  /**
+   * The client supports sending a will save request and
+   * waits for a response providing text edits which will
+   * be applied to the document before it is saved.
+   */
+  @Pure
+  public Boolean getWillSaveWaitUntil() {
+    return this.willSaveWaitUntil;
+  }
+  
+  /**
+   * The client supports sending a will save request and
+   * waits for a response providing text edits which will
+   * be applied to the document before it is saved.
+   */
+  public void setWillSaveWaitUntil(final Boolean willSaveWaitUntil) {
+    this.willSaveWaitUntil = willSaveWaitUntil;
+  }
+  
+  /**
+   * The client supports did save notifications.
+   */
+  @Pure
+  public Boolean getDidSave() {
+    return this.didSave;
+  }
+  
+  /**
+   * The client supports did save notifications.
+   */
+  public void setDidSave(final Boolean didSave) {
+    this.didSave = didSave;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("willSave", this.willSave);
+    b.add("willSaveWaitUntil", this.willSaveWaitUntil);
+    b.add("didSave", this.didSave);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    SynchronizationCapabilities other = (SynchronizationCapabilities) obj;
+    if (this.willSave == null) {
+      if (other.willSave != null)
+        return false;
+    } else if (!this.willSave.equals(other.willSave))
+      return false;
+    if (this.willSaveWaitUntil == null) {
+      if (other.willSaveWaitUntil != null)
+        return false;
+    } else if (!this.willSaveWaitUntil.equals(other.willSaveWaitUntil))
+      return false;
+    if (this.didSave == null) {
+      if (other.didSave != null)
+        return false;
+    } else if (!this.didSave.equals(other.didSave))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.willSave== null) ? 0 : this.willSave.hashCode());
+    result = prime * result + ((this.willSaveWaitUntil== null) ? 0 : this.willSaveWaitUntil.hashCode());
+    return prime * result + ((this.didSave== null) ? 0 : this.didSave.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/TextDocumentChangeRegistrationOptions.java b/java/org/eclipse/lsp4j/TextDocumentChangeRegistrationOptions.java
new file mode 100644
index 0000000..490cf62
--- /dev/null
+++ b/java/org/eclipse/lsp4j/TextDocumentChangeRegistrationOptions.java
@@ -0,0 +1,92 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.TextDocumentRegistrationOptions;
+import org.eclipse.lsp4j.TextDocumentSyncKind;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Describe options to be used when registered for text document change events.
+ */
+@SuppressWarnings("all")
+public class TextDocumentChangeRegistrationOptions extends TextDocumentRegistrationOptions {
+  /**
+   * How documents are synced to the server. See TextDocumentSyncKind.Full
+   * and TextDocumentSyncKind.Incremental.
+   */
+  @NonNull
+  private TextDocumentSyncKind syncKind;
+  
+  public TextDocumentChangeRegistrationOptions() {
+  }
+  
+  public TextDocumentChangeRegistrationOptions(@NonNull final TextDocumentSyncKind syncKind) {
+    this.syncKind = Preconditions.<TextDocumentSyncKind>checkNotNull(syncKind, "syncKind");
+  }
+  
+  /**
+   * How documents are synced to the server. See TextDocumentSyncKind.Full
+   * and TextDocumentSyncKind.Incremental.
+   */
+  @Pure
+  @NonNull
+  public TextDocumentSyncKind getSyncKind() {
+    return this.syncKind;
+  }
+  
+  /**
+   * How documents are synced to the server. See TextDocumentSyncKind.Full
+   * and TextDocumentSyncKind.Incremental.
+   */
+  public void setSyncKind(@NonNull final TextDocumentSyncKind syncKind) {
+    this.syncKind = Preconditions.checkNotNull(syncKind, "syncKind");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("syncKind", this.syncKind);
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    TextDocumentChangeRegistrationOptions other = (TextDocumentChangeRegistrationOptions) obj;
+    if (this.syncKind == null) {
+      if (other.syncKind != null)
+        return false;
+    } else if (!this.syncKind.equals(other.syncKind))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.syncKind== null) ? 0 : this.syncKind.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/TextDocumentClientCapabilities.java b/java/org/eclipse/lsp4j/TextDocumentClientCapabilities.java
new file mode 100644
index 0000000..0210335
--- /dev/null
+++ b/java/org/eclipse/lsp4j/TextDocumentClientCapabilities.java
@@ -0,0 +1,866 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import com.google.common.annotations.Beta;
+import org.eclipse.lsp4j.CallHierarchyCapabilities;
+import org.eclipse.lsp4j.CodeActionCapabilities;
+import org.eclipse.lsp4j.CodeLensCapabilities;
+import org.eclipse.lsp4j.ColorProviderCapabilities;
+import org.eclipse.lsp4j.CompletionCapabilities;
+import org.eclipse.lsp4j.DeclarationCapabilities;
+import org.eclipse.lsp4j.DefinitionCapabilities;
+import org.eclipse.lsp4j.DocumentHighlightCapabilities;
+import org.eclipse.lsp4j.DocumentLinkCapabilities;
+import org.eclipse.lsp4j.DocumentSymbolCapabilities;
+import org.eclipse.lsp4j.FoldingRangeCapabilities;
+import org.eclipse.lsp4j.FormattingCapabilities;
+import org.eclipse.lsp4j.HoverCapabilities;
+import org.eclipse.lsp4j.ImplementationCapabilities;
+import org.eclipse.lsp4j.LinkedEditingRangeCapabilities;
+import org.eclipse.lsp4j.MonikerCapabilities;
+import org.eclipse.lsp4j.OnTypeFormattingCapabilities;
+import org.eclipse.lsp4j.PublishDiagnosticsCapabilities;
+import org.eclipse.lsp4j.RangeFormattingCapabilities;
+import org.eclipse.lsp4j.ReferencesCapabilities;
+import org.eclipse.lsp4j.RenameCapabilities;
+import org.eclipse.lsp4j.SelectionRangeCapabilities;
+import org.eclipse.lsp4j.SemanticTokensCapabilities;
+import org.eclipse.lsp4j.SignatureHelpCapabilities;
+import org.eclipse.lsp4j.SynchronizationCapabilities;
+import org.eclipse.lsp4j.TypeDefinitionCapabilities;
+import org.eclipse.lsp4j.TypeHierarchyCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Text document specific client capabilities.
+ */
+@SuppressWarnings("all")
+public class TextDocumentClientCapabilities {
+  private SynchronizationCapabilities synchronization;
+  
+  /**
+   * Capabilities specific to the {@code textDocument/completion}
+   */
+  private CompletionCapabilities completion;
+  
+  /**
+   * Capabilities specific to the {@code textDocument/hover}
+   */
+  private HoverCapabilities hover;
+  
+  /**
+   * Capabilities specific to the {@code textDocument/signatureHelp}
+   */
+  private SignatureHelpCapabilities signatureHelp;
+  
+  /**
+   * Capabilities specific to the {@code textDocument/references}
+   */
+  private ReferencesCapabilities references;
+  
+  /**
+   * Capabilities specific to the {@code textDocument/documentHighlight}
+   */
+  private DocumentHighlightCapabilities documentHighlight;
+  
+  /**
+   * Capabilities specific to the {@code textDocument/documentSymbol}
+   */
+  private DocumentSymbolCapabilities documentSymbol;
+  
+  /**
+   * Capabilities specific to the {@code textDocument/formatting}
+   */
+  private FormattingCapabilities formatting;
+  
+  /**
+   * Capabilities specific to the {@code textDocument/rangeFormatting}
+   */
+  private RangeFormattingCapabilities rangeFormatting;
+  
+  /**
+   * Capabilities specific to the {@code textDocument/onTypeFormatting}
+   */
+  private OnTypeFormattingCapabilities onTypeFormatting;
+  
+  /**
+   * Capabilities specific to the {@code textDocument/declaration}
+   * <p>
+   * Since 3.14.0
+   */
+  private DeclarationCapabilities declaration;
+  
+  /**
+   * Capabilities specific to the {@code textDocument/definition}
+   * <p>
+   * Since 3.14.0
+   */
+  private DefinitionCapabilities definition;
+  
+  /**
+   * Capabilities specific to the {@code textDocument/typeDefinition}
+   * <p>
+   * Since 3.6.0
+   */
+  private TypeDefinitionCapabilities typeDefinition;
+  
+  /**
+   * Capabilities specific to the {@code textDocument/implementation}
+   * <p>
+   * Since 3.6.0
+   */
+  private ImplementationCapabilities implementation;
+  
+  /**
+   * Capabilities specific to the {@code textDocument/codeAction}
+   */
+  private CodeActionCapabilities codeAction;
+  
+  /**
+   * Capabilities specific to the {@code textDocument/codeLens}
+   */
+  private CodeLensCapabilities codeLens;
+  
+  /**
+   * Capabilities specific to the {@code textDocument/documentLink}
+   */
+  private DocumentLinkCapabilities documentLink;
+  
+  /**
+   * Capabilities specific to the {@code textDocument/documentColor} and the
+   * {@code textDocument/colorPresentation} request.
+   * <p>
+   * Since 3.6.0
+   */
+  private ColorProviderCapabilities colorProvider;
+  
+  /**
+   * Capabilities specific to the {@code textDocument/rename}
+   */
+  private RenameCapabilities rename;
+  
+  /**
+   * Capabilities specific to {@code textDocument/publishDiagnostics}.
+   */
+  private PublishDiagnosticsCapabilities publishDiagnostics;
+  
+  /**
+   * Capabilities specific to {@code textDocument/foldingRange} requests.
+   * <p>
+   * Since 3.10.0
+   */
+  private FoldingRangeCapabilities foldingRange;
+  
+  /**
+   * Capabilities specific to {@code textDocument/typeHierarchy}.
+   */
+  @Beta
+  private TypeHierarchyCapabilities typeHierarchyCapabilities;
+  
+  /**
+   * Capabilities specific to {@code textDocument/prepareCallHierarchy}.
+   * <p>
+   * Since 3.16.0
+   */
+  private CallHierarchyCapabilities callHierarchy;
+  
+  /**
+   * Capabilities specific to `textDocument/selectionRange` requests
+   * <p>
+   * Since 3.15.0
+   */
+  private SelectionRangeCapabilities selectionRange;
+  
+  /**
+   * Capabilities specific to {@code textDocument/semanticTokens}.
+   * <p>
+   * Since 3.16.0
+   */
+  private SemanticTokensCapabilities semanticTokens;
+  
+  /**
+   * Capabilities specific to the {@code textDocument/moniker} request.
+   * <p>
+   * Since 3.16.0
+   */
+  private MonikerCapabilities moniker;
+  
+  /**
+   * Capabilities specific to the {@code textDocument/linkedEditingRange} request.
+   * <p>
+   * Since 3.16.0
+   */
+  private LinkedEditingRangeCapabilities linkedEditingRange;
+  
+  @Pure
+  public SynchronizationCapabilities getSynchronization() {
+    return this.synchronization;
+  }
+  
+  public void setSynchronization(final SynchronizationCapabilities synchronization) {
+    this.synchronization = synchronization;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/completion}
+   */
+  @Pure
+  public CompletionCapabilities getCompletion() {
+    return this.completion;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/completion}
+   */
+  public void setCompletion(final CompletionCapabilities completion) {
+    this.completion = completion;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/hover}
+   */
+  @Pure
+  public HoverCapabilities getHover() {
+    return this.hover;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/hover}
+   */
+  public void setHover(final HoverCapabilities hover) {
+    this.hover = hover;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/signatureHelp}
+   */
+  @Pure
+  public SignatureHelpCapabilities getSignatureHelp() {
+    return this.signatureHelp;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/signatureHelp}
+   */
+  public void setSignatureHelp(final SignatureHelpCapabilities signatureHelp) {
+    this.signatureHelp = signatureHelp;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/references}
+   */
+  @Pure
+  public ReferencesCapabilities getReferences() {
+    return this.references;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/references}
+   */
+  public void setReferences(final ReferencesCapabilities references) {
+    this.references = references;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/documentHighlight}
+   */
+  @Pure
+  public DocumentHighlightCapabilities getDocumentHighlight() {
+    return this.documentHighlight;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/documentHighlight}
+   */
+  public void setDocumentHighlight(final DocumentHighlightCapabilities documentHighlight) {
+    this.documentHighlight = documentHighlight;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/documentSymbol}
+   */
+  @Pure
+  public DocumentSymbolCapabilities getDocumentSymbol() {
+    return this.documentSymbol;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/documentSymbol}
+   */
+  public void setDocumentSymbol(final DocumentSymbolCapabilities documentSymbol) {
+    this.documentSymbol = documentSymbol;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/formatting}
+   */
+  @Pure
+  public FormattingCapabilities getFormatting() {
+    return this.formatting;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/formatting}
+   */
+  public void setFormatting(final FormattingCapabilities formatting) {
+    this.formatting = formatting;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/rangeFormatting}
+   */
+  @Pure
+  public RangeFormattingCapabilities getRangeFormatting() {
+    return this.rangeFormatting;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/rangeFormatting}
+   */
+  public void setRangeFormatting(final RangeFormattingCapabilities rangeFormatting) {
+    this.rangeFormatting = rangeFormatting;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/onTypeFormatting}
+   */
+  @Pure
+  public OnTypeFormattingCapabilities getOnTypeFormatting() {
+    return this.onTypeFormatting;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/onTypeFormatting}
+   */
+  public void setOnTypeFormatting(final OnTypeFormattingCapabilities onTypeFormatting) {
+    this.onTypeFormatting = onTypeFormatting;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/declaration}
+   * <p>
+   * Since 3.14.0
+   */
+  @Pure
+  public DeclarationCapabilities getDeclaration() {
+    return this.declaration;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/declaration}
+   * <p>
+   * Since 3.14.0
+   */
+  public void setDeclaration(final DeclarationCapabilities declaration) {
+    this.declaration = declaration;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/definition}
+   * <p>
+   * Since 3.14.0
+   */
+  @Pure
+  public DefinitionCapabilities getDefinition() {
+    return this.definition;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/definition}
+   * <p>
+   * Since 3.14.0
+   */
+  public void setDefinition(final DefinitionCapabilities definition) {
+    this.definition = definition;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/typeDefinition}
+   * <p>
+   * Since 3.6.0
+   */
+  @Pure
+  public TypeDefinitionCapabilities getTypeDefinition() {
+    return this.typeDefinition;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/typeDefinition}
+   * <p>
+   * Since 3.6.0
+   */
+  public void setTypeDefinition(final TypeDefinitionCapabilities typeDefinition) {
+    this.typeDefinition = typeDefinition;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/implementation}
+   * <p>
+   * Since 3.6.0
+   */
+  @Pure
+  public ImplementationCapabilities getImplementation() {
+    return this.implementation;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/implementation}
+   * <p>
+   * Since 3.6.0
+   */
+  public void setImplementation(final ImplementationCapabilities implementation) {
+    this.implementation = implementation;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/codeAction}
+   */
+  @Pure
+  public CodeActionCapabilities getCodeAction() {
+    return this.codeAction;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/codeAction}
+   */
+  public void setCodeAction(final CodeActionCapabilities codeAction) {
+    this.codeAction = codeAction;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/codeLens}
+   */
+  @Pure
+  public CodeLensCapabilities getCodeLens() {
+    return this.codeLens;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/codeLens}
+   */
+  public void setCodeLens(final CodeLensCapabilities codeLens) {
+    this.codeLens = codeLens;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/documentLink}
+   */
+  @Pure
+  public DocumentLinkCapabilities getDocumentLink() {
+    return this.documentLink;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/documentLink}
+   */
+  public void setDocumentLink(final DocumentLinkCapabilities documentLink) {
+    this.documentLink = documentLink;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/documentColor} and the
+   * {@code textDocument/colorPresentation} request.
+   * <p>
+   * Since 3.6.0
+   */
+  @Pure
+  public ColorProviderCapabilities getColorProvider() {
+    return this.colorProvider;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/documentColor} and the
+   * {@code textDocument/colorPresentation} request.
+   * <p>
+   * Since 3.6.0
+   */
+  public void setColorProvider(final ColorProviderCapabilities colorProvider) {
+    this.colorProvider = colorProvider;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/rename}
+   */
+  @Pure
+  public RenameCapabilities getRename() {
+    return this.rename;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/rename}
+   */
+  public void setRename(final RenameCapabilities rename) {
+    this.rename = rename;
+  }
+  
+  /**
+   * Capabilities specific to {@code textDocument/publishDiagnostics}.
+   */
+  @Pure
+  public PublishDiagnosticsCapabilities getPublishDiagnostics() {
+    return this.publishDiagnostics;
+  }
+  
+  /**
+   * Capabilities specific to {@code textDocument/publishDiagnostics}.
+   */
+  public void setPublishDiagnostics(final PublishDiagnosticsCapabilities publishDiagnostics) {
+    this.publishDiagnostics = publishDiagnostics;
+  }
+  
+  /**
+   * Capabilities specific to {@code textDocument/foldingRange} requests.
+   * <p>
+   * Since 3.10.0
+   */
+  @Pure
+  public FoldingRangeCapabilities getFoldingRange() {
+    return this.foldingRange;
+  }
+  
+  /**
+   * Capabilities specific to {@code textDocument/foldingRange} requests.
+   * <p>
+   * Since 3.10.0
+   */
+  public void setFoldingRange(final FoldingRangeCapabilities foldingRange) {
+    this.foldingRange = foldingRange;
+  }
+  
+  /**
+   * Capabilities specific to {@code textDocument/typeHierarchy}.
+   */
+  @Pure
+  public TypeHierarchyCapabilities getTypeHierarchyCapabilities() {
+    return this.typeHierarchyCapabilities;
+  }
+  
+  /**
+   * Capabilities specific to {@code textDocument/typeHierarchy}.
+   */
+  public void setTypeHierarchyCapabilities(final TypeHierarchyCapabilities typeHierarchyCapabilities) {
+    this.typeHierarchyCapabilities = typeHierarchyCapabilities;
+  }
+  
+  /**
+   * Capabilities specific to {@code textDocument/prepareCallHierarchy}.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public CallHierarchyCapabilities getCallHierarchy() {
+    return this.callHierarchy;
+  }
+  
+  /**
+   * Capabilities specific to {@code textDocument/prepareCallHierarchy}.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setCallHierarchy(final CallHierarchyCapabilities callHierarchy) {
+    this.callHierarchy = callHierarchy;
+  }
+  
+  /**
+   * Capabilities specific to `textDocument/selectionRange` requests
+   * <p>
+   * Since 3.15.0
+   */
+  @Pure
+  public SelectionRangeCapabilities getSelectionRange() {
+    return this.selectionRange;
+  }
+  
+  /**
+   * Capabilities specific to `textDocument/selectionRange` requests
+   * <p>
+   * Since 3.15.0
+   */
+  public void setSelectionRange(final SelectionRangeCapabilities selectionRange) {
+    this.selectionRange = selectionRange;
+  }
+  
+  /**
+   * Capabilities specific to {@code textDocument/semanticTokens}.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public SemanticTokensCapabilities getSemanticTokens() {
+    return this.semanticTokens;
+  }
+  
+  /**
+   * Capabilities specific to {@code textDocument/semanticTokens}.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setSemanticTokens(final SemanticTokensCapabilities semanticTokens) {
+    this.semanticTokens = semanticTokens;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/moniker} request.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public MonikerCapabilities getMoniker() {
+    return this.moniker;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/moniker} request.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setMoniker(final MonikerCapabilities moniker) {
+    this.moniker = moniker;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/linkedEditingRange} request.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public LinkedEditingRangeCapabilities getLinkedEditingRange() {
+    return this.linkedEditingRange;
+  }
+  
+  /**
+   * Capabilities specific to the {@code textDocument/linkedEditingRange} request.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setLinkedEditingRange(final LinkedEditingRangeCapabilities linkedEditingRange) {
+    this.linkedEditingRange = linkedEditingRange;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("synchronization", this.synchronization);
+    b.add("completion", this.completion);
+    b.add("hover", this.hover);
+    b.add("signatureHelp", this.signatureHelp);
+    b.add("references", this.references);
+    b.add("documentHighlight", this.documentHighlight);
+    b.add("documentSymbol", this.documentSymbol);
+    b.add("formatting", this.formatting);
+    b.add("rangeFormatting", this.rangeFormatting);
+    b.add("onTypeFormatting", this.onTypeFormatting);
+    b.add("declaration", this.declaration);
+    b.add("definition", this.definition);
+    b.add("typeDefinition", this.typeDefinition);
+    b.add("implementation", this.implementation);
+    b.add("codeAction", this.codeAction);
+    b.add("codeLens", this.codeLens);
+    b.add("documentLink", this.documentLink);
+    b.add("colorProvider", this.colorProvider);
+    b.add("rename", this.rename);
+    b.add("publishDiagnostics", this.publishDiagnostics);
+    b.add("foldingRange", this.foldingRange);
+    b.add("typeHierarchyCapabilities", this.typeHierarchyCapabilities);
+    b.add("callHierarchy", this.callHierarchy);
+    b.add("selectionRange", this.selectionRange);
+    b.add("semanticTokens", this.semanticTokens);
+    b.add("moniker", this.moniker);
+    b.add("linkedEditingRange", this.linkedEditingRange);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    TextDocumentClientCapabilities other = (TextDocumentClientCapabilities) obj;
+    if (this.synchronization == null) {
+      if (other.synchronization != null)
+        return false;
+    } else if (!this.synchronization.equals(other.synchronization))
+      return false;
+    if (this.completion == null) {
+      if (other.completion != null)
+        return false;
+    } else if (!this.completion.equals(other.completion))
+      return false;
+    if (this.hover == null) {
+      if (other.hover != null)
+        return false;
+    } else if (!this.hover.equals(other.hover))
+      return false;
+    if (this.signatureHelp == null) {
+      if (other.signatureHelp != null)
+        return false;
+    } else if (!this.signatureHelp.equals(other.signatureHelp))
+      return false;
+    if (this.references == null) {
+      if (other.references != null)
+        return false;
+    } else if (!this.references.equals(other.references))
+      return false;
+    if (this.documentHighlight == null) {
+      if (other.documentHighlight != null)
+        return false;
+    } else if (!this.documentHighlight.equals(other.documentHighlight))
+      return false;
+    if (this.documentSymbol == null) {
+      if (other.documentSymbol != null)
+        return false;
+    } else if (!this.documentSymbol.equals(other.documentSymbol))
+      return false;
+    if (this.formatting == null) {
+      if (other.formatting != null)
+        return false;
+    } else if (!this.formatting.equals(other.formatting))
+      return false;
+    if (this.rangeFormatting == null) {
+      if (other.rangeFormatting != null)
+        return false;
+    } else if (!this.rangeFormatting.equals(other.rangeFormatting))
+      return false;
+    if (this.onTypeFormatting == null) {
+      if (other.onTypeFormatting != null)
+        return false;
+    } else if (!this.onTypeFormatting.equals(other.onTypeFormatting))
+      return false;
+    if (this.declaration == null) {
+      if (other.declaration != null)
+        return false;
+    } else if (!this.declaration.equals(other.declaration))
+      return false;
+    if (this.definition == null) {
+      if (other.definition != null)
+        return false;
+    } else if (!this.definition.equals(other.definition))
+      return false;
+    if (this.typeDefinition == null) {
+      if (other.typeDefinition != null)
+        return false;
+    } else if (!this.typeDefinition.equals(other.typeDefinition))
+      return false;
+    if (this.implementation == null) {
+      if (other.implementation != null)
+        return false;
+    } else if (!this.implementation.equals(other.implementation))
+      return false;
+    if (this.codeAction == null) {
+      if (other.codeAction != null)
+        return false;
+    } else if (!this.codeAction.equals(other.codeAction))
+      return false;
+    if (this.codeLens == null) {
+      if (other.codeLens != null)
+        return false;
+    } else if (!this.codeLens.equals(other.codeLens))
+      return false;
+    if (this.documentLink == null) {
+      if (other.documentLink != null)
+        return false;
+    } else if (!this.documentLink.equals(other.documentLink))
+      return false;
+    if (this.colorProvider == null) {
+      if (other.colorProvider != null)
+        return false;
+    } else if (!this.colorProvider.equals(other.colorProvider))
+      return false;
+    if (this.rename == null) {
+      if (other.rename != null)
+        return false;
+    } else if (!this.rename.equals(other.rename))
+      return false;
+    if (this.publishDiagnostics == null) {
+      if (other.publishDiagnostics != null)
+        return false;
+    } else if (!this.publishDiagnostics.equals(other.publishDiagnostics))
+      return false;
+    if (this.foldingRange == null) {
+      if (other.foldingRange != null)
+        return false;
+    } else if (!this.foldingRange.equals(other.foldingRange))
+      return false;
+    if (this.typeHierarchyCapabilities == null) {
+      if (other.typeHierarchyCapabilities != null)
+        return false;
+    } else if (!this.typeHierarchyCapabilities.equals(other.typeHierarchyCapabilities))
+      return false;
+    if (this.callHierarchy == null) {
+      if (other.callHierarchy != null)
+        return false;
+    } else if (!this.callHierarchy.equals(other.callHierarchy))
+      return false;
+    if (this.selectionRange == null) {
+      if (other.selectionRange != null)
+        return false;
+    } else if (!this.selectionRange.equals(other.selectionRange))
+      return false;
+    if (this.semanticTokens == null) {
+      if (other.semanticTokens != null)
+        return false;
+    } else if (!this.semanticTokens.equals(other.semanticTokens))
+      return false;
+    if (this.moniker == null) {
+      if (other.moniker != null)
+        return false;
+    } else if (!this.moniker.equals(other.moniker))
+      return false;
+    if (this.linkedEditingRange == null) {
+      if (other.linkedEditingRange != null)
+        return false;
+    } else if (!this.linkedEditingRange.equals(other.linkedEditingRange))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.synchronization== null) ? 0 : this.synchronization.hashCode());
+    result = prime * result + ((this.completion== null) ? 0 : this.completion.hashCode());
+    result = prime * result + ((this.hover== null) ? 0 : this.hover.hashCode());
+    result = prime * result + ((this.signatureHelp== null) ? 0 : this.signatureHelp.hashCode());
+    result = prime * result + ((this.references== null) ? 0 : this.references.hashCode());
+    result = prime * result + ((this.documentHighlight== null) ? 0 : this.documentHighlight.hashCode());
+    result = prime * result + ((this.documentSymbol== null) ? 0 : this.documentSymbol.hashCode());
+    result = prime * result + ((this.formatting== null) ? 0 : this.formatting.hashCode());
+    result = prime * result + ((this.rangeFormatting== null) ? 0 : this.rangeFormatting.hashCode());
+    result = prime * result + ((this.onTypeFormatting== null) ? 0 : this.onTypeFormatting.hashCode());
+    result = prime * result + ((this.declaration== null) ? 0 : this.declaration.hashCode());
+    result = prime * result + ((this.definition== null) ? 0 : this.definition.hashCode());
+    result = prime * result + ((this.typeDefinition== null) ? 0 : this.typeDefinition.hashCode());
+    result = prime * result + ((this.implementation== null) ? 0 : this.implementation.hashCode());
+    result = prime * result + ((this.codeAction== null) ? 0 : this.codeAction.hashCode());
+    result = prime * result + ((this.codeLens== null) ? 0 : this.codeLens.hashCode());
+    result = prime * result + ((this.documentLink== null) ? 0 : this.documentLink.hashCode());
+    result = prime * result + ((this.colorProvider== null) ? 0 : this.colorProvider.hashCode());
+    result = prime * result + ((this.rename== null) ? 0 : this.rename.hashCode());
+    result = prime * result + ((this.publishDiagnostics== null) ? 0 : this.publishDiagnostics.hashCode());
+    result = prime * result + ((this.foldingRange== null) ? 0 : this.foldingRange.hashCode());
+    result = prime * result + ((this.typeHierarchyCapabilities== null) ? 0 : this.typeHierarchyCapabilities.hashCode());
+    result = prime * result + ((this.callHierarchy== null) ? 0 : this.callHierarchy.hashCode());
+    result = prime * result + ((this.selectionRange== null) ? 0 : this.selectionRange.hashCode());
+    result = prime * result + ((this.semanticTokens== null) ? 0 : this.semanticTokens.hashCode());
+    result = prime * result + ((this.moniker== null) ? 0 : this.moniker.hashCode());
+    return prime * result + ((this.linkedEditingRange== null) ? 0 : this.linkedEditingRange.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/TextDocumentContentChangeEvent.java b/java/org/eclipse/lsp4j/TextDocumentContentChangeEvent.java
new file mode 100644
index 0000000..d311c51
--- /dev/null
+++ b/java/org/eclipse/lsp4j/TextDocumentContentChangeEvent.java
@@ -0,0 +1,157 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * An event describing a change to a text document. If range and rangeLength are omitted the new text is considered
+ * to be the full content of the document.
+ */
+@SuppressWarnings("all")
+public class TextDocumentContentChangeEvent {
+  /**
+   * The range of the document that changed.
+   */
+  private Range range;
+  
+  /**
+   * The length of the range that got replaced.
+   * 
+   * @deprecated Use range instead.
+   */
+  @Deprecated
+  private Integer rangeLength;
+  
+  /**
+   * The new text of the range/document.
+   */
+  @NonNull
+  private String text;
+  
+  public TextDocumentContentChangeEvent() {
+  }
+  
+  public TextDocumentContentChangeEvent(@NonNull final String text) {
+    this.text = Preconditions.<String>checkNotNull(text, "text");
+  }
+  
+  public TextDocumentContentChangeEvent(final Range range, final Integer rangeLength, @NonNull final String text) {
+    this(text);
+    this.range = range;
+    this.rangeLength = rangeLength;
+  }
+  
+  /**
+   * The range of the document that changed.
+   */
+  @Pure
+  public Range getRange() {
+    return this.range;
+  }
+  
+  /**
+   * The range of the document that changed.
+   */
+  public void setRange(final Range range) {
+    this.range = range;
+  }
+  
+  /**
+   * The length of the range that got replaced.
+   * 
+   * @deprecated Use range instead.
+   */
+  @Pure
+  @Deprecated
+  public Integer getRangeLength() {
+    return this.rangeLength;
+  }
+  
+  /**
+   * The length of the range that got replaced.
+   * 
+   * @deprecated Use range instead.
+   */
+  @Deprecated
+  public void setRangeLength(final Integer rangeLength) {
+    this.rangeLength = rangeLength;
+  }
+  
+  /**
+   * The new text of the range/document.
+   */
+  @Pure
+  @NonNull
+  public String getText() {
+    return this.text;
+  }
+  
+  /**
+   * The new text of the range/document.
+   */
+  public void setText(@NonNull final String text) {
+    this.text = Preconditions.checkNotNull(text, "text");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("range", this.range);
+    b.add("rangeLength", this.rangeLength);
+    b.add("text", this.text);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    TextDocumentContentChangeEvent other = (TextDocumentContentChangeEvent) obj;
+    if (this.range == null) {
+      if (other.range != null)
+        return false;
+    } else if (!this.range.equals(other.range))
+      return false;
+    if (this.rangeLength == null) {
+      if (other.rangeLength != null)
+        return false;
+    } else if (!this.rangeLength.equals(other.rangeLength))
+      return false;
+    if (this.text == null) {
+      if (other.text != null)
+        return false;
+    } else if (!this.text.equals(other.text))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.range== null) ? 0 : this.range.hashCode());
+    result = prime * result + ((this.rangeLength== null) ? 0 : this.rangeLength.hashCode());
+    return prime * result + ((this.text== null) ? 0 : this.text.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/TextDocumentEdit.java b/java/org/eclipse/lsp4j/TextDocumentEdit.java
new file mode 100644
index 0000000..2dfaa5d
--- /dev/null
+++ b/java/org/eclipse/lsp4j/TextDocumentEdit.java
@@ -0,0 +1,121 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.TextEdit;
+import org.eclipse.lsp4j.VersionedTextDocumentIdentifier;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Describes textual changes on a single text document.
+ * The text document is referred to as a {@link VersionedTextDocumentIdentifier}
+ * to allow clients to check the text document version before an edit is applied.
+ */
+@SuppressWarnings("all")
+public class TextDocumentEdit {
+  /**
+   * The text document to change.
+   */
+  @NonNull
+  private VersionedTextDocumentIdentifier textDocument;
+  
+  /**
+   * The edits to be applied
+   */
+  @NonNull
+  private List<TextEdit> edits;
+  
+  public TextDocumentEdit() {
+  }
+  
+  public TextDocumentEdit(@NonNull final VersionedTextDocumentIdentifier textDocument, @NonNull final List<TextEdit> edits) {
+    this.textDocument = Preconditions.<VersionedTextDocumentIdentifier>checkNotNull(textDocument, "textDocument");
+    this.edits = Preconditions.<List<TextEdit>>checkNotNull(edits, "edits");
+  }
+  
+  /**
+   * The text document to change.
+   */
+  @Pure
+  @NonNull
+  public VersionedTextDocumentIdentifier getTextDocument() {
+    return this.textDocument;
+  }
+  
+  /**
+   * The text document to change.
+   */
+  public void setTextDocument(@NonNull final VersionedTextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.checkNotNull(textDocument, "textDocument");
+  }
+  
+  /**
+   * The edits to be applied
+   */
+  @Pure
+  @NonNull
+  public List<TextEdit> getEdits() {
+    return this.edits;
+  }
+  
+  /**
+   * The edits to be applied
+   */
+  public void setEdits(@NonNull final List<TextEdit> edits) {
+    this.edits = Preconditions.checkNotNull(edits, "edits");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("textDocument", this.textDocument);
+    b.add("edits", this.edits);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    TextDocumentEdit other = (TextDocumentEdit) obj;
+    if (this.textDocument == null) {
+      if (other.textDocument != null)
+        return false;
+    } else if (!this.textDocument.equals(other.textDocument))
+      return false;
+    if (this.edits == null) {
+      if (other.edits != null)
+        return false;
+    } else if (!this.edits.equals(other.edits))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.textDocument== null) ? 0 : this.textDocument.hashCode());
+    return prime * result + ((this.edits== null) ? 0 : this.edits.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/TextDocumentIdentifier.java b/java/org/eclipse/lsp4j/TextDocumentIdentifier.java
new file mode 100644
index 0000000..8805a9a
--- /dev/null
+++ b/java/org/eclipse/lsp4j/TextDocumentIdentifier.java
@@ -0,0 +1,84 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Text documents are identified using an URI. On the protocol level URI's are passed as strings.
+ */
+@SuppressWarnings("all")
+public class TextDocumentIdentifier {
+  /**
+   * The text document's uri.
+   */
+  @NonNull
+  private String uri;
+  
+  public TextDocumentIdentifier() {
+  }
+  
+  public TextDocumentIdentifier(@NonNull final String uri) {
+    this.uri = Preconditions.<String>checkNotNull(uri, "uri");
+  }
+  
+  /**
+   * The text document's uri.
+   */
+  @Pure
+  @NonNull
+  public String getUri() {
+    return this.uri;
+  }
+  
+  /**
+   * The text document's uri.
+   */
+  public void setUri(@NonNull final String uri) {
+    this.uri = Preconditions.checkNotNull(uri, "uri");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("uri", this.uri);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    TextDocumentIdentifier other = (TextDocumentIdentifier) obj;
+    if (this.uri == null) {
+      if (other.uri != null)
+        return false;
+    } else if (!this.uri.equals(other.uri))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.uri== null) ? 0 : this.uri.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/TextDocumentItem.java b/java/org/eclipse/lsp4j/TextDocumentItem.java
new file mode 100644
index 0000000..df16dd7
--- /dev/null
+++ b/java/org/eclipse/lsp4j/TextDocumentItem.java
@@ -0,0 +1,171 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * An item to transfer a text document from the client to the server.
+ */
+@SuppressWarnings("all")
+public class TextDocumentItem {
+  /**
+   * The text document's uri.
+   */
+  @NonNull
+  private String uri;
+  
+  /**
+   * The text document's language identifier
+   */
+  @NonNull
+  private String languageId;
+  
+  /**
+   * The version number of this document (it will strictly increase after each change, including undo/redo).
+   */
+  private int version;
+  
+  /**
+   * The content of the opened text document.
+   */
+  @NonNull
+  private String text;
+  
+  public TextDocumentItem() {
+  }
+  
+  public TextDocumentItem(@NonNull final String uri, @NonNull final String languageId, final int version, @NonNull final String text) {
+    this.uri = Preconditions.<String>checkNotNull(uri, "uri");
+    this.languageId = Preconditions.<String>checkNotNull(languageId, "languageId");
+    this.version = version;
+    this.text = Preconditions.<String>checkNotNull(text, "text");
+  }
+  
+  /**
+   * The text document's uri.
+   */
+  @Pure
+  @NonNull
+  public String getUri() {
+    return this.uri;
+  }
+  
+  /**
+   * The text document's uri.
+   */
+  public void setUri(@NonNull final String uri) {
+    this.uri = Preconditions.checkNotNull(uri, "uri");
+  }
+  
+  /**
+   * The text document's language identifier
+   */
+  @Pure
+  @NonNull
+  public String getLanguageId() {
+    return this.languageId;
+  }
+  
+  /**
+   * The text document's language identifier
+   */
+  public void setLanguageId(@NonNull final String languageId) {
+    this.languageId = Preconditions.checkNotNull(languageId, "languageId");
+  }
+  
+  /**
+   * The version number of this document (it will strictly increase after each change, including undo/redo).
+   */
+  @Pure
+  public int getVersion() {
+    return this.version;
+  }
+  
+  /**
+   * The version number of this document (it will strictly increase after each change, including undo/redo).
+   */
+  public void setVersion(final int version) {
+    this.version = version;
+  }
+  
+  /**
+   * The content of the opened text document.
+   */
+  @Pure
+  @NonNull
+  public String getText() {
+    return this.text;
+  }
+  
+  /**
+   * The content of the opened text document.
+   */
+  public void setText(@NonNull final String text) {
+    this.text = Preconditions.checkNotNull(text, "text");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("uri", this.uri);
+    b.add("languageId", this.languageId);
+    b.add("version", this.version);
+    b.add("text", this.text);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    TextDocumentItem other = (TextDocumentItem) obj;
+    if (this.uri == null) {
+      if (other.uri != null)
+        return false;
+    } else if (!this.uri.equals(other.uri))
+      return false;
+    if (this.languageId == null) {
+      if (other.languageId != null)
+        return false;
+    } else if (!this.languageId.equals(other.languageId))
+      return false;
+    if (other.version != this.version)
+      return false;
+    if (this.text == null) {
+      if (other.text != null)
+        return false;
+    } else if (!this.text.equals(other.text))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.uri== null) ? 0 : this.uri.hashCode());
+    result = prime * result + ((this.languageId== null) ? 0 : this.languageId.hashCode());
+    result = prime * result + this.version;
+    return prime * result + ((this.text== null) ? 0 : this.text.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/TextDocumentPositionAndWorkDoneProgressAndPartialResultParams.java b/java/org/eclipse/lsp4j/TextDocumentPositionAndWorkDoneProgressAndPartialResultParams.java
new file mode 100644
index 0000000..00b81a0
--- /dev/null
+++ b/java/org/eclipse/lsp4j/TextDocumentPositionAndWorkDoneProgressAndPartialResultParams.java
@@ -0,0 +1,115 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.PartialResultParams;
+import org.eclipse.lsp4j.Position;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.TextDocumentPositionAndWorkDoneProgressParams;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Abstract class which extends TextDocumentPosition and implements work done progress and partial result request parameter.
+ * It is not present in protocol specification, so it's just "dry" class.
+ * <p>
+ * Since 3.15.0
+ */
+@SuppressWarnings("all")
+public abstract class TextDocumentPositionAndWorkDoneProgressAndPartialResultParams extends TextDocumentPositionAndWorkDoneProgressParams implements PartialResultParams {
+  /**
+   * An optional token that a server can use to report partial results (e.g. streaming) to
+   * the client.
+   */
+  private Either<String, Integer> partialResultToken;
+  
+  public TextDocumentPositionAndWorkDoneProgressAndPartialResultParams() {
+  }
+  
+  public TextDocumentPositionAndWorkDoneProgressAndPartialResultParams(@NonNull final TextDocumentIdentifier textDocument, @NonNull final Position position) {
+    super(textDocument, position);
+  }
+  
+  /**
+   * An optional token that a server can use to report partial results (e.g. streaming) to
+   * the client.
+   */
+  @Pure
+  @Override
+  public Either<String, Integer> getPartialResultToken() {
+    return this.partialResultToken;
+  }
+  
+  /**
+   * An optional token that a server can use to report partial results (e.g. streaming) to
+   * the client.
+   */
+  public void setPartialResultToken(final Either<String, Integer> partialResultToken) {
+    this.partialResultToken = partialResultToken;
+  }
+  
+  public void setPartialResultToken(final String partialResultToken) {
+    if (partialResultToken == null) {
+      this.partialResultToken = null;
+      return;
+    }
+    this.partialResultToken = Either.forLeft(partialResultToken);
+  }
+  
+  public void setPartialResultToken(final Integer partialResultToken) {
+    if (partialResultToken == null) {
+      this.partialResultToken = null;
+      return;
+    }
+    this.partialResultToken = Either.forRight(partialResultToken);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("partialResultToken", this.partialResultToken);
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("textDocument", getTextDocument());
+    b.add("uri", getUri());
+    b.add("position", getPosition());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    TextDocumentPositionAndWorkDoneProgressAndPartialResultParams other = (TextDocumentPositionAndWorkDoneProgressAndPartialResultParams) obj;
+    if (this.partialResultToken == null) {
+      if (other.partialResultToken != null)
+        return false;
+    } else if (!this.partialResultToken.equals(other.partialResultToken))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.partialResultToken== null) ? 0 : this.partialResultToken.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/TextDocumentPositionAndWorkDoneProgressParams.java b/java/org/eclipse/lsp4j/TextDocumentPositionAndWorkDoneProgressParams.java
new file mode 100644
index 0000000..a22d371
--- /dev/null
+++ b/java/org/eclipse/lsp4j/TextDocumentPositionAndWorkDoneProgressParams.java
@@ -0,0 +1,111 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.Position;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.TextDocumentPositionParams;
+import org.eclipse.lsp4j.WorkDoneProgressParams;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Abstract class which extends TextDocumentPosition and implements work done progress request parameter.
+ * It is not present in protocol specification, so it's just "dry" class.
+ * <p>
+ * Since 3.15.0
+ */
+@SuppressWarnings("all")
+public abstract class TextDocumentPositionAndWorkDoneProgressParams extends TextDocumentPositionParams implements WorkDoneProgressParams {
+  /**
+   * An optional token that a server can use to report work done progress.
+   */
+  private Either<String, Integer> workDoneToken;
+  
+  public TextDocumentPositionAndWorkDoneProgressParams() {
+  }
+  
+  public TextDocumentPositionAndWorkDoneProgressParams(@NonNull final TextDocumentIdentifier textDocument, @NonNull final Position position) {
+    super(textDocument, position);
+  }
+  
+  /**
+   * An optional token that a server can use to report work done progress.
+   */
+  @Pure
+  @Override
+  public Either<String, Integer> getWorkDoneToken() {
+    return this.workDoneToken;
+  }
+  
+  /**
+   * An optional token that a server can use to report work done progress.
+   */
+  public void setWorkDoneToken(final Either<String, Integer> workDoneToken) {
+    this.workDoneToken = workDoneToken;
+  }
+  
+  public void setWorkDoneToken(final String workDoneToken) {
+    if (workDoneToken == null) {
+      this.workDoneToken = null;
+      return;
+    }
+    this.workDoneToken = Either.forLeft(workDoneToken);
+  }
+  
+  public void setWorkDoneToken(final Integer workDoneToken) {
+    if (workDoneToken == null) {
+      this.workDoneToken = null;
+      return;
+    }
+    this.workDoneToken = Either.forRight(workDoneToken);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneToken", this.workDoneToken);
+    b.add("textDocument", getTextDocument());
+    b.add("uri", getUri());
+    b.add("position", getPosition());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    TextDocumentPositionAndWorkDoneProgressParams other = (TextDocumentPositionAndWorkDoneProgressParams) obj;
+    if (this.workDoneToken == null) {
+      if (other.workDoneToken != null)
+        return false;
+    } else if (!this.workDoneToken.equals(other.workDoneToken))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.workDoneToken== null) ? 0 : this.workDoneToken.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/TextDocumentPositionParams.java b/java/org/eclipse/lsp4j/TextDocumentPositionParams.java
new file mode 100644
index 0000000..a41fd88
--- /dev/null
+++ b/java/org/eclipse/lsp4j/TextDocumentPositionParams.java
@@ -0,0 +1,155 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.Position;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A parameter literal used in requests to pass a text document and a position inside that document.
+ */
+@SuppressWarnings("all")
+public class TextDocumentPositionParams {
+  /**
+   * The text document.
+   */
+  @NonNull
+  private TextDocumentIdentifier textDocument;
+  
+  /**
+   * Legacy property to support protocol version 1.0 requests.
+   */
+  @Deprecated
+  private String uri;
+  
+  /**
+   * The position inside the text document.
+   */
+  @NonNull
+  private Position position;
+  
+  public TextDocumentPositionParams() {
+  }
+  
+  public TextDocumentPositionParams(@NonNull final TextDocumentIdentifier textDocument, @NonNull final Position position) {
+    this.textDocument = Preconditions.<TextDocumentIdentifier>checkNotNull(textDocument, "textDocument");
+    this.position = Preconditions.<Position>checkNotNull(position, "position");
+  }
+  
+  @Deprecated
+  public TextDocumentPositionParams(@NonNull final TextDocumentIdentifier textDocument, final String uri, @NonNull final Position position) {
+    this.textDocument = Preconditions.<TextDocumentIdentifier>checkNotNull(textDocument, "textDocument");
+    this.uri = uri;
+    this.position = Preconditions.<Position>checkNotNull(position, "position");
+  }
+  
+  /**
+   * The text document.
+   */
+  @Pure
+  @NonNull
+  public TextDocumentIdentifier getTextDocument() {
+    return this.textDocument;
+  }
+  
+  /**
+   * The text document.
+   */
+  public void setTextDocument(@NonNull final TextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.checkNotNull(textDocument, "textDocument");
+  }
+  
+  /**
+   * Legacy property to support protocol version 1.0 requests.
+   */
+  @Pure
+  @Deprecated
+  public String getUri() {
+    return this.uri;
+  }
+  
+  /**
+   * Legacy property to support protocol version 1.0 requests.
+   */
+  @Deprecated
+  public void setUri(final String uri) {
+    this.uri = uri;
+  }
+  
+  /**
+   * The position inside the text document.
+   */
+  @Pure
+  @NonNull
+  public Position getPosition() {
+    return this.position;
+  }
+  
+  /**
+   * The position inside the text document.
+   */
+  public void setPosition(@NonNull final Position position) {
+    this.position = Preconditions.checkNotNull(position, "position");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("textDocument", this.textDocument);
+    b.add("uri", this.uri);
+    b.add("position", this.position);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    TextDocumentPositionParams other = (TextDocumentPositionParams) obj;
+    if (this.textDocument == null) {
+      if (other.textDocument != null)
+        return false;
+    } else if (!this.textDocument.equals(other.textDocument))
+      return false;
+    if (this.uri == null) {
+      if (other.uri != null)
+        return false;
+    } else if (!this.uri.equals(other.uri))
+      return false;
+    if (this.position == null) {
+      if (other.position != null)
+        return false;
+    } else if (!this.position.equals(other.position))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.textDocument== null) ? 0 : this.textDocument.hashCode());
+    result = prime * result + ((this.uri== null) ? 0 : this.uri.hashCode());
+    return prime * result + ((this.position== null) ? 0 : this.position.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/TextDocumentRegistrationOptions.java b/java/org/eclipse/lsp4j/TextDocumentRegistrationOptions.java
new file mode 100644
index 0000000..a80d482
--- /dev/null
+++ b/java/org/eclipse/lsp4j/TextDocumentRegistrationOptions.java
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.List;
+import org.eclipse.lsp4j.DocumentFilter;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Since most of the registration options require to specify a document selector there is
+ * a base interface that can be used.
+ */
+@SuppressWarnings("all")
+public class TextDocumentRegistrationOptions {
+  /**
+   * A document selector to identify the scope of the registration. If set to null
+   * the document selector provided on the client side will be used.
+   */
+  private List<DocumentFilter> documentSelector;
+  
+  public TextDocumentRegistrationOptions() {
+  }
+  
+  public TextDocumentRegistrationOptions(final List<DocumentFilter> documentSelector) {
+    this.documentSelector = documentSelector;
+  }
+  
+  /**
+   * A document selector to identify the scope of the registration. If set to null
+   * the document selector provided on the client side will be used.
+   */
+  @Pure
+  public List<DocumentFilter> getDocumentSelector() {
+    return this.documentSelector;
+  }
+  
+  /**
+   * A document selector to identify the scope of the registration. If set to null
+   * the document selector provided on the client side will be used.
+   */
+  public void setDocumentSelector(final List<DocumentFilter> documentSelector) {
+    this.documentSelector = documentSelector;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("documentSelector", this.documentSelector);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    TextDocumentRegistrationOptions other = (TextDocumentRegistrationOptions) obj;
+    if (this.documentSelector == null) {
+      if (other.documentSelector != null)
+        return false;
+    } else if (!this.documentSelector.equals(other.documentSelector))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.documentSelector== null) ? 0 : this.documentSelector.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/TextDocumentSaveReason.java b/java/org/eclipse/lsp4j/TextDocumentSaveReason.java
new file mode 100644
index 0000000..7cfef6a
--- /dev/null
+++ b/java/org/eclipse/lsp4j/TextDocumentSaveReason.java
@@ -0,0 +1,52 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j;
+
+/**
+ * Represents reasons why a text document is saved.
+ */
+public enum TextDocumentSaveReason {
+
+	/**
+	 * Manually triggered, e.g. by the user pressing save, by starting debugging,
+     * or by an API call.
+	 */
+	Manual(1),
+
+	/**
+	 * Automatic after a delay.
+	 */
+	AfterDelay(2),
+	
+	/**
+	 * When the editor lost focus.
+	 */
+	FocusOut(3);
+
+	private final int value;
+	
+	TextDocumentSaveReason(int value) {
+		this.value = value;
+	}
+	
+	public int getValue() {
+		return value;
+	}
+	
+	public static TextDocumentSaveReason forValue(int value) {
+		TextDocumentSaveReason[] allValues = TextDocumentSaveReason.values();
+		if (value < 1 || value > allValues.length)
+			throw new IllegalArgumentException("Illegal enum value: " + value);
+		return allValues[value - 1];
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/TextDocumentSaveRegistrationOptions.java b/java/org/eclipse/lsp4j/TextDocumentSaveRegistrationOptions.java
new file mode 100644
index 0000000..773b7bb
--- /dev/null
+++ b/java/org/eclipse/lsp4j/TextDocumentSaveRegistrationOptions.java
@@ -0,0 +1,81 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.TextDocumentRegistrationOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class TextDocumentSaveRegistrationOptions extends TextDocumentRegistrationOptions {
+  /**
+   * The client is supposed to include the content on save.
+   */
+  private Boolean includeText;
+  
+  public TextDocumentSaveRegistrationOptions() {
+  }
+  
+  public TextDocumentSaveRegistrationOptions(final Boolean includeText) {
+    this.includeText = includeText;
+  }
+  
+  /**
+   * The client is supposed to include the content on save.
+   */
+  @Pure
+  public Boolean getIncludeText() {
+    return this.includeText;
+  }
+  
+  /**
+   * The client is supposed to include the content on save.
+   */
+  public void setIncludeText(final Boolean includeText) {
+    this.includeText = includeText;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("includeText", this.includeText);
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    TextDocumentSaveRegistrationOptions other = (TextDocumentSaveRegistrationOptions) obj;
+    if (this.includeText == null) {
+      if (other.includeText != null)
+        return false;
+    } else if (!this.includeText.equals(other.includeText))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.includeText== null) ? 0 : this.includeText.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/TextDocumentSyncKind.java b/java/org/eclipse/lsp4j/TextDocumentSyncKind.java
new file mode 100644
index 0000000..4221c17
--- /dev/null
+++ b/java/org/eclipse/lsp4j/TextDocumentSyncKind.java
@@ -0,0 +1,42 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j;
+
+/**
+ * Defines how text documents are synced.
+ */
+public enum TextDocumentSyncKind {
+	
+	/**
+	 * Documents should not be synced at all.
+	 */
+	None,
+	
+	/**
+	 * Documents are synced by always sending the full content of the document.
+	 */
+	Full,
+	
+	/**
+	 * Documents are synced by sending the full content on open. After that only incremental
+	 * updates to the document are send.
+	 */
+	Incremental;
+	
+	public static TextDocumentSyncKind forValue(int value) {
+		TextDocumentSyncKind[] allValues = TextDocumentSyncKind.values();
+		if (value < 0 || value >= allValues.length)
+			throw new IllegalArgumentException("Illegal enum value: " + value);
+		return allValues[value];
+	}
+	
+}
diff --git a/java/org/eclipse/lsp4j/TextDocumentSyncOptions.java b/java/org/eclipse/lsp4j/TextDocumentSyncOptions.java
new file mode 100644
index 0000000..eb6b689
--- /dev/null
+++ b/java/org/eclipse/lsp4j/TextDocumentSyncOptions.java
@@ -0,0 +1,202 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.SaveOptions;
+import org.eclipse.lsp4j.TextDocumentSyncKind;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class TextDocumentSyncOptions {
+  /**
+   * Open and close notifications are sent to the server.
+   */
+  private Boolean openClose;
+  
+  /**
+   * Change notifications are sent to the server. See TextDocumentSyncKind.None, TextDocumentSyncKind.Full
+   * and TextDocumentSyncKind.Incremental.
+   */
+  private TextDocumentSyncKind change;
+  
+  /**
+   * Will save notifications are sent to the server.
+   */
+  private Boolean willSave;
+  
+  /**
+   * Will save wait until requests are sent to the server.
+   */
+  private Boolean willSaveWaitUntil;
+  
+  /**
+   * Save notifications are sent to the server.
+   */
+  private Either<Boolean, SaveOptions> save;
+  
+  /**
+   * Open and close notifications are sent to the server.
+   */
+  @Pure
+  public Boolean getOpenClose() {
+    return this.openClose;
+  }
+  
+  /**
+   * Open and close notifications are sent to the server.
+   */
+  public void setOpenClose(final Boolean openClose) {
+    this.openClose = openClose;
+  }
+  
+  /**
+   * Change notifications are sent to the server. See TextDocumentSyncKind.None, TextDocumentSyncKind.Full
+   * and TextDocumentSyncKind.Incremental.
+   */
+  @Pure
+  public TextDocumentSyncKind getChange() {
+    return this.change;
+  }
+  
+  /**
+   * Change notifications are sent to the server. See TextDocumentSyncKind.None, TextDocumentSyncKind.Full
+   * and TextDocumentSyncKind.Incremental.
+   */
+  public void setChange(final TextDocumentSyncKind change) {
+    this.change = change;
+  }
+  
+  /**
+   * Will save notifications are sent to the server.
+   */
+  @Pure
+  public Boolean getWillSave() {
+    return this.willSave;
+  }
+  
+  /**
+   * Will save notifications are sent to the server.
+   */
+  public void setWillSave(final Boolean willSave) {
+    this.willSave = willSave;
+  }
+  
+  /**
+   * Will save wait until requests are sent to the server.
+   */
+  @Pure
+  public Boolean getWillSaveWaitUntil() {
+    return this.willSaveWaitUntil;
+  }
+  
+  /**
+   * Will save wait until requests are sent to the server.
+   */
+  public void setWillSaveWaitUntil(final Boolean willSaveWaitUntil) {
+    this.willSaveWaitUntil = willSaveWaitUntil;
+  }
+  
+  /**
+   * Save notifications are sent to the server.
+   */
+  @Pure
+  public Either<Boolean, SaveOptions> getSave() {
+    return this.save;
+  }
+  
+  /**
+   * Save notifications are sent to the server.
+   */
+  public void setSave(final Either<Boolean, SaveOptions> save) {
+    this.save = save;
+  }
+  
+  public void setSave(final Boolean save) {
+    if (save == null) {
+      this.save = null;
+      return;
+    }
+    this.save = Either.forLeft(save);
+  }
+  
+  public void setSave(final SaveOptions save) {
+    if (save == null) {
+      this.save = null;
+      return;
+    }
+    this.save = Either.forRight(save);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("openClose", this.openClose);
+    b.add("change", this.change);
+    b.add("willSave", this.willSave);
+    b.add("willSaveWaitUntil", this.willSaveWaitUntil);
+    b.add("save", this.save);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    TextDocumentSyncOptions other = (TextDocumentSyncOptions) obj;
+    if (this.openClose == null) {
+      if (other.openClose != null)
+        return false;
+    } else if (!this.openClose.equals(other.openClose))
+      return false;
+    if (this.change == null) {
+      if (other.change != null)
+        return false;
+    } else if (!this.change.equals(other.change))
+      return false;
+    if (this.willSave == null) {
+      if (other.willSave != null)
+        return false;
+    } else if (!this.willSave.equals(other.willSave))
+      return false;
+    if (this.willSaveWaitUntil == null) {
+      if (other.willSaveWaitUntil != null)
+        return false;
+    } else if (!this.willSaveWaitUntil.equals(other.willSaveWaitUntil))
+      return false;
+    if (this.save == null) {
+      if (other.save != null)
+        return false;
+    } else if (!this.save.equals(other.save))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.openClose== null) ? 0 : this.openClose.hashCode());
+    result = prime * result + ((this.change== null) ? 0 : this.change.hashCode());
+    result = prime * result + ((this.willSave== null) ? 0 : this.willSave.hashCode());
+    result = prime * result + ((this.willSaveWaitUntil== null) ? 0 : this.willSaveWaitUntil.hashCode());
+    return prime * result + ((this.save== null) ? 0 : this.save.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/TextEdit.java b/java/org/eclipse/lsp4j/TextEdit.java
new file mode 100644
index 0000000..989ac44
--- /dev/null
+++ b/java/org/eclipse/lsp4j/TextEdit.java
@@ -0,0 +1,117 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A textual edit applicable to a text document.
+ */
+@SuppressWarnings("all")
+public class TextEdit {
+  /**
+   * The range of the text document to be manipulated. To insert text into a document create a range where start === end.
+   */
+  @NonNull
+  private Range range;
+  
+  /**
+   * The string to be inserted. For delete operations use an empty string.
+   */
+  @NonNull
+  private String newText;
+  
+  public TextEdit() {
+  }
+  
+  public TextEdit(@NonNull final Range range, @NonNull final String newText) {
+    this.range = Preconditions.<Range>checkNotNull(range, "range");
+    this.newText = Preconditions.<String>checkNotNull(newText, "newText");
+  }
+  
+  /**
+   * The range of the text document to be manipulated. To insert text into a document create a range where start === end.
+   */
+  @Pure
+  @NonNull
+  public Range getRange() {
+    return this.range;
+  }
+  
+  /**
+   * The range of the text document to be manipulated. To insert text into a document create a range where start === end.
+   */
+  public void setRange(@NonNull final Range range) {
+    this.range = Preconditions.checkNotNull(range, "range");
+  }
+  
+  /**
+   * The string to be inserted. For delete operations use an empty string.
+   */
+  @Pure
+  @NonNull
+  public String getNewText() {
+    return this.newText;
+  }
+  
+  /**
+   * The string to be inserted. For delete operations use an empty string.
+   */
+  public void setNewText(@NonNull final String newText) {
+    this.newText = Preconditions.checkNotNull(newText, "newText");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("range", this.range);
+    b.add("newText", this.newText);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    TextEdit other = (TextEdit) obj;
+    if (this.range == null) {
+      if (other.range != null)
+        return false;
+    } else if (!this.range.equals(other.range))
+      return false;
+    if (this.newText == null) {
+      if (other.newText != null)
+        return false;
+    } else if (!this.newText.equals(other.newText))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.range== null) ? 0 : this.range.hashCode());
+    return prime * result + ((this.newText== null) ? 0 : this.newText.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/TokenFormat.java b/java/org/eclipse/lsp4j/TokenFormat.java
new file mode 100644
index 0000000..c576b4e
--- /dev/null
+++ b/java/org/eclipse/lsp4j/TokenFormat.java
@@ -0,0 +1,23 @@
+/**
+ * Copyright (c) 2020 Eric Dallo.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+/**
+ * Since 3.16.0
+ */
+public final class TokenFormat {
+    private TokenFormat() {
+    }
+
+    public static final String Relative = "relative";
+
+}
diff --git a/java/org/eclipse/lsp4j/TraceValue.java b/java/org/eclipse/lsp4j/TraceValue.java
new file mode 100644
index 0000000..8f51eab
--- /dev/null
+++ b/java/org/eclipse/lsp4j/TraceValue.java
@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) 2020 TypeFox and others.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+package org.eclipse.lsp4j;
+
+/**
+ * A TraceValue represents the level of verbosity with which the server systematically reports its execution 
+ * trace using {@code $/logTrace} notifications. The initial trace value is set by the client at initialization and 
+ * can be modified later using the {@code $/setTrace} notification.
+ */
+public class TraceValue {
+	private TraceValue() {
+	}
+
+	public static final String Off = "off";
+
+	public static final String Message = "message";
+
+	public static final String Verbose = "verbose";
+}
diff --git a/java/org/eclipse/lsp4j/TypeDefinitionCapabilities.java b/java/org/eclipse/lsp4j/TypeDefinitionCapabilities.java
new file mode 100644
index 0000000..35b0c3e
--- /dev/null
+++ b/java/org/eclipse/lsp4j/TypeDefinitionCapabilities.java
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the `textDocument/typeDefinition`
+ * <p>
+ * Since 3.6.0
+ */
+@SuppressWarnings("all")
+public class TypeDefinitionCapabilities extends DynamicRegistrationCapabilities {
+  /**
+   * The client supports additional metadata in the form of definition links.
+   * <p>
+   * Since 3.14.0
+   */
+  private Boolean linkSupport;
+  
+  public TypeDefinitionCapabilities() {
+  }
+  
+  public TypeDefinitionCapabilities(final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+  }
+  
+  public TypeDefinitionCapabilities(final Boolean dynamicRegistration, final Boolean linkSupport) {
+    super(dynamicRegistration);
+    this.linkSupport = linkSupport;
+  }
+  
+  /**
+   * The client supports additional metadata in the form of definition links.
+   * <p>
+   * Since 3.14.0
+   */
+  @Pure
+  public Boolean getLinkSupport() {
+    return this.linkSupport;
+  }
+  
+  /**
+   * The client supports additional metadata in the form of definition links.
+   * <p>
+   * Since 3.14.0
+   */
+  public void setLinkSupport(final Boolean linkSupport) {
+    this.linkSupport = linkSupport;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("linkSupport", this.linkSupport);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    TypeDefinitionCapabilities other = (TypeDefinitionCapabilities) obj;
+    if (this.linkSupport == null) {
+      if (other.linkSupport != null)
+        return false;
+    } else if (!this.linkSupport.equals(other.linkSupport))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.linkSupport== null) ? 0 : this.linkSupport.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/TypeDefinitionOptions.java b/java/org/eclipse/lsp4j/TypeDefinitionOptions.java
new file mode 100644
index 0000000..e4745d5
--- /dev/null
+++ b/java/org/eclipse/lsp4j/TypeDefinitionOptions.java
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class TypeDefinitionOptions extends AbstractWorkDoneProgressOptions {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/TypeDefinitionParams.java b/java/org/eclipse/lsp4j/TypeDefinitionParams.java
new file mode 100644
index 0000000..5eda4e6
--- /dev/null
+++ b/java/org/eclipse/lsp4j/TypeDefinitionParams.java
@@ -0,0 +1,65 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.Position;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.TextDocumentPositionAndWorkDoneProgressAndPartialResultParams;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The go to type definition request is sent from the client to the server to resolve the type definition
+ * location of a symbol at a given text document position.
+ */
+@SuppressWarnings("all")
+public class TypeDefinitionParams extends TextDocumentPositionAndWorkDoneProgressAndPartialResultParams {
+  public TypeDefinitionParams() {
+  }
+  
+  public TypeDefinitionParams(@NonNull final TextDocumentIdentifier textDocument, @NonNull final Position position) {
+    super(textDocument, position);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("partialResultToken", getPartialResultToken());
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("textDocument", getTextDocument());
+    b.add("uri", getUri());
+    b.add("position", getPosition());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/TypeDefinitionRegistrationOptions.java b/java/org/eclipse/lsp4j/TypeDefinitionRegistrationOptions.java
new file mode 100644
index 0000000..6e44b9b
--- /dev/null
+++ b/java/org/eclipse/lsp4j/TypeDefinitionRegistrationOptions.java
@@ -0,0 +1,85 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractTextDocumentRegistrationAndWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class TypeDefinitionRegistrationOptions extends AbstractTextDocumentRegistrationAndWorkDoneProgressOptions {
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  private String id;
+  
+  public TypeDefinitionRegistrationOptions() {
+  }
+  
+  public TypeDefinitionRegistrationOptions(final String id) {
+    this.id = id;
+  }
+  
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  @Pure
+  public String getId() {
+    return this.id;
+  }
+  
+  /**
+   * The id used to register the request. The id can be used to deregister
+   * the request again. See also Registration#id.
+   */
+  public void setId(final String id) {
+    this.id = id;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("id", this.id);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    b.add("documentSelector", getDocumentSelector());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    TypeDefinitionRegistrationOptions other = (TypeDefinitionRegistrationOptions) obj;
+    if (this.id == null) {
+      if (other.id != null)
+        return false;
+    } else if (!this.id.equals(other.id))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.id== null) ? 0 : this.id.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/TypeHierarchyCapabilities.java b/java/org/eclipse/lsp4j/TypeHierarchyCapabilities.java
new file mode 100644
index 0000000..154a139
--- /dev/null
+++ b/java/org/eclipse/lsp4j/TypeHierarchyCapabilities.java
@@ -0,0 +1,63 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import com.google.common.annotations.Beta;
+import org.eclipse.lsp4j.DynamicRegistrationCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the {@code textDocument/typeHierarchy}.
+ * <p>
+ * <b>Note:</b> the <a href=
+ * "https://github.com/Microsoft/vscode-languageserver-node/pull/426">{@code textDocument/typeHierarchy}
+ * language feature</a> is not yet part of the official LSP specification.
+ */
+@Beta
+@SuppressWarnings("all")
+public class TypeHierarchyCapabilities extends DynamicRegistrationCapabilities {
+  public TypeHierarchyCapabilities() {
+  }
+  
+  public TypeHierarchyCapabilities(final Boolean dynamicRegistration) {
+    super(dynamicRegistration);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("dynamicRegistration", getDynamicRegistration());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/TypeHierarchyDirection.java b/java/org/eclipse/lsp4j/TypeHierarchyDirection.java
new file mode 100644
index 0000000..88f4869
--- /dev/null
+++ b/java/org/eclipse/lsp4j/TypeHierarchyDirection.java
@@ -0,0 +1,57 @@
+/******************************************************************************
+ * Copyright (c) 2019 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.services.TextDocumentService;
+
+/**
+ * Direction specific to the
+ * {@link TextDocumentService#typeHierarchy(TypeHierarchyParams)
+ * textDocument/typeHierarchy} and
+ * {@link TextDocumentService#resolveTypeHierarchy(ResolveTypeHierarchyItemParams)
+ * typeHierarchy/resolve} LS methods.
+ * 
+ * <p>
+ * Valid values are:
+ * <ul>
+ * <li>{@link TypeHierarchyDirection#Children Children},</li>
+ * <li>{@link TypeHierarchyDirection#Parents Parents},</li>
+ * <li>{@link TypeHierarchyDirection#Both Both}.</li>
+ * </ul>
+ *
+ */
+public enum TypeHierarchyDirection {
+
+	/**
+	 * Flag for retrieving/resolving the subtypes. Value: {@code 0}.
+	 */
+	Children,
+
+	/**
+	 * Flag to use when retrieving/resolving the supertypes. Value: {@code 1}.
+	 */
+	Parents,
+
+	/**
+	 * Flag for resolving both the super- and subtypes. Value: {@code 2}.
+	 */
+	Both;
+
+	public static TypeHierarchyDirection forValue(int value) {
+		TypeHierarchyDirection[] values = TypeHierarchyDirection.values();
+		if (value < 0 || value >= values.length) {
+			throw new IllegalArgumentException("Illegal enum value: " + value);
+		}
+		return values[value];
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/TypeHierarchyItem.java b/java/org/eclipse/lsp4j/TypeHierarchyItem.java
new file mode 100644
index 0000000..ebf9f7c
--- /dev/null
+++ b/java/org/eclipse/lsp4j/TypeHierarchyItem.java
@@ -0,0 +1,365 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import com.google.common.annotations.Beta;
+import com.google.gson.annotations.JsonAdapter;
+import java.util.List;
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.SymbolKind;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Representation of an item that carries type information (such as class, interface, enumeration, etc) with additional parentage details.
+ */
+@Beta
+@SuppressWarnings("all")
+public class TypeHierarchyItem {
+  /**
+   * The human readable name of the hierarchy item.
+   */
+  @NonNull
+  private String name;
+  
+  /**
+   * Optional detail for the hierarchy item. It can be, for instance, the signature of a function or method.
+   */
+  private String detail;
+  
+  /**
+   * The kind of the hierarchy item. For instance, class or interface.
+   */
+  @NonNull
+  private SymbolKind kind;
+  
+  /**
+   * {@code true} if the hierarchy item is deprecated. Otherwise, {@code false}. It is {@code false} by default.
+   */
+  private Boolean deprecated;
+  
+  /**
+   * The URI of the text document where this type hierarchy item belongs to.
+   */
+  @NonNull
+  private String uri;
+  
+  /**
+   * The range enclosing this type hierarchy item not including leading/trailing whitespace but everything else
+   * like comments. This information is typically used to determine if the clients cursor is inside the type
+   * hierarchy item to reveal in the symbol in the UI.
+   * 
+   * @see TypeHierarchyItem#selectionRange
+   */
+  @NonNull
+  private Range range;
+  
+  /**
+   * The range that should be selected and revealed when this type hierarchy item is being picked, e.g the name of a function.
+   * Must be contained by the the {@link TypeHierarchyItem#getRange range}.
+   * 
+   * @see TypeHierarchyItem#range
+   */
+  @NonNull
+  private Range selectionRange;
+  
+  /**
+   * If this type hierarchy item is resolved, it contains the direct parents. Could be empty if the item does not have any
+   * direct parents. If not defined, the parents have not been resolved yet.
+   */
+  private List<TypeHierarchyItem> parents;
+  
+  /**
+   * If this type hierarchy item is resolved, it contains the direct children of the current item.
+   * Could be empty if the item does not have any descendants. If not defined, the children have not been resolved.
+   */
+  private List<TypeHierarchyItem> children;
+  
+  /**
+   * An optional data field can be used to identify a type hierarchy item in a resolve request.
+   */
+  @JsonAdapter(JsonElementTypeAdapter.Factory.class)
+  private Object data;
+  
+  /**
+   * The human readable name of the hierarchy item.
+   */
+  @Pure
+  @NonNull
+  public String getName() {
+    return this.name;
+  }
+  
+  /**
+   * The human readable name of the hierarchy item.
+   */
+  public void setName(@NonNull final String name) {
+    this.name = Preconditions.checkNotNull(name, "name");
+  }
+  
+  /**
+   * Optional detail for the hierarchy item. It can be, for instance, the signature of a function or method.
+   */
+  @Pure
+  public String getDetail() {
+    return this.detail;
+  }
+  
+  /**
+   * Optional detail for the hierarchy item. It can be, for instance, the signature of a function or method.
+   */
+  public void setDetail(final String detail) {
+    this.detail = detail;
+  }
+  
+  /**
+   * The kind of the hierarchy item. For instance, class or interface.
+   */
+  @Pure
+  @NonNull
+  public SymbolKind getKind() {
+    return this.kind;
+  }
+  
+  /**
+   * The kind of the hierarchy item. For instance, class or interface.
+   */
+  public void setKind(@NonNull final SymbolKind kind) {
+    this.kind = Preconditions.checkNotNull(kind, "kind");
+  }
+  
+  /**
+   * {@code true} if the hierarchy item is deprecated. Otherwise, {@code false}. It is {@code false} by default.
+   */
+  @Pure
+  public Boolean getDeprecated() {
+    return this.deprecated;
+  }
+  
+  /**
+   * {@code true} if the hierarchy item is deprecated. Otherwise, {@code false}. It is {@code false} by default.
+   */
+  public void setDeprecated(final Boolean deprecated) {
+    this.deprecated = deprecated;
+  }
+  
+  /**
+   * The URI of the text document where this type hierarchy item belongs to.
+   */
+  @Pure
+  @NonNull
+  public String getUri() {
+    return this.uri;
+  }
+  
+  /**
+   * The URI of the text document where this type hierarchy item belongs to.
+   */
+  public void setUri(@NonNull final String uri) {
+    this.uri = Preconditions.checkNotNull(uri, "uri");
+  }
+  
+  /**
+   * The range enclosing this type hierarchy item not including leading/trailing whitespace but everything else
+   * like comments. This information is typically used to determine if the clients cursor is inside the type
+   * hierarchy item to reveal in the symbol in the UI.
+   * 
+   * @see TypeHierarchyItem#selectionRange
+   */
+  @Pure
+  @NonNull
+  public Range getRange() {
+    return this.range;
+  }
+  
+  /**
+   * The range enclosing this type hierarchy item not including leading/trailing whitespace but everything else
+   * like comments. This information is typically used to determine if the clients cursor is inside the type
+   * hierarchy item to reveal in the symbol in the UI.
+   * 
+   * @see TypeHierarchyItem#selectionRange
+   */
+  public void setRange(@NonNull final Range range) {
+    this.range = Preconditions.checkNotNull(range, "range");
+  }
+  
+  /**
+   * The range that should be selected and revealed when this type hierarchy item is being picked, e.g the name of a function.
+   * Must be contained by the the {@link TypeHierarchyItem#getRange range}.
+   * 
+   * @see TypeHierarchyItem#range
+   */
+  @Pure
+  @NonNull
+  public Range getSelectionRange() {
+    return this.selectionRange;
+  }
+  
+  /**
+   * The range that should be selected and revealed when this type hierarchy item is being picked, e.g the name of a function.
+   * Must be contained by the the {@link TypeHierarchyItem#getRange range}.
+   * 
+   * @see TypeHierarchyItem#range
+   */
+  public void setSelectionRange(@NonNull final Range selectionRange) {
+    this.selectionRange = Preconditions.checkNotNull(selectionRange, "selectionRange");
+  }
+  
+  /**
+   * If this type hierarchy item is resolved, it contains the direct parents. Could be empty if the item does not have any
+   * direct parents. If not defined, the parents have not been resolved yet.
+   */
+  @Pure
+  public List<TypeHierarchyItem> getParents() {
+    return this.parents;
+  }
+  
+  /**
+   * If this type hierarchy item is resolved, it contains the direct parents. Could be empty if the item does not have any
+   * direct parents. If not defined, the parents have not been resolved yet.
+   */
+  public void setParents(final List<TypeHierarchyItem> parents) {
+    this.parents = parents;
+  }
+  
+  /**
+   * If this type hierarchy item is resolved, it contains the direct children of the current item.
+   * Could be empty if the item does not have any descendants. If not defined, the children have not been resolved.
+   */
+  @Pure
+  public List<TypeHierarchyItem> getChildren() {
+    return this.children;
+  }
+  
+  /**
+   * If this type hierarchy item is resolved, it contains the direct children of the current item.
+   * Could be empty if the item does not have any descendants. If not defined, the children have not been resolved.
+   */
+  public void setChildren(final List<TypeHierarchyItem> children) {
+    this.children = children;
+  }
+  
+  /**
+   * An optional data field can be used to identify a type hierarchy item in a resolve request.
+   */
+  @Pure
+  public Object getData() {
+    return this.data;
+  }
+  
+  /**
+   * An optional data field can be used to identify a type hierarchy item in a resolve request.
+   */
+  public void setData(final Object data) {
+    this.data = data;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("name", this.name);
+    b.add("detail", this.detail);
+    b.add("kind", this.kind);
+    b.add("deprecated", this.deprecated);
+    b.add("uri", this.uri);
+    b.add("range", this.range);
+    b.add("selectionRange", this.selectionRange);
+    b.add("parents", this.parents);
+    b.add("children", this.children);
+    b.add("data", this.data);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    TypeHierarchyItem other = (TypeHierarchyItem) obj;
+    if (this.name == null) {
+      if (other.name != null)
+        return false;
+    } else if (!this.name.equals(other.name))
+      return false;
+    if (this.detail == null) {
+      if (other.detail != null)
+        return false;
+    } else if (!this.detail.equals(other.detail))
+      return false;
+    if (this.kind == null) {
+      if (other.kind != null)
+        return false;
+    } else if (!this.kind.equals(other.kind))
+      return false;
+    if (this.deprecated == null) {
+      if (other.deprecated != null)
+        return false;
+    } else if (!this.deprecated.equals(other.deprecated))
+      return false;
+    if (this.uri == null) {
+      if (other.uri != null)
+        return false;
+    } else if (!this.uri.equals(other.uri))
+      return false;
+    if (this.range == null) {
+      if (other.range != null)
+        return false;
+    } else if (!this.range.equals(other.range))
+      return false;
+    if (this.selectionRange == null) {
+      if (other.selectionRange != null)
+        return false;
+    } else if (!this.selectionRange.equals(other.selectionRange))
+      return false;
+    if (this.parents == null) {
+      if (other.parents != null)
+        return false;
+    } else if (!this.parents.equals(other.parents))
+      return false;
+    if (this.children == null) {
+      if (other.children != null)
+        return false;
+    } else if (!this.children.equals(other.children))
+      return false;
+    if (this.data == null) {
+      if (other.data != null)
+        return false;
+    } else if (!this.data.equals(other.data))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.name== null) ? 0 : this.name.hashCode());
+    result = prime * result + ((this.detail== null) ? 0 : this.detail.hashCode());
+    result = prime * result + ((this.kind== null) ? 0 : this.kind.hashCode());
+    result = prime * result + ((this.deprecated== null) ? 0 : this.deprecated.hashCode());
+    result = prime * result + ((this.uri== null) ? 0 : this.uri.hashCode());
+    result = prime * result + ((this.range== null) ? 0 : this.range.hashCode());
+    result = prime * result + ((this.selectionRange== null) ? 0 : this.selectionRange.hashCode());
+    result = prime * result + ((this.parents== null) ? 0 : this.parents.hashCode());
+    result = prime * result + ((this.children== null) ? 0 : this.children.hashCode());
+    return prime * result + ((this.data== null) ? 0 : this.data.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/TypeHierarchyParams.java b/java/org/eclipse/lsp4j/TypeHierarchyParams.java
new file mode 100644
index 0000000..d796521
--- /dev/null
+++ b/java/org/eclipse/lsp4j/TypeHierarchyParams.java
@@ -0,0 +1,110 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import com.google.common.annotations.Beta;
+import org.eclipse.lsp4j.TextDocumentPositionParams;
+import org.eclipse.lsp4j.TypeHierarchyDirection;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The type hierarchy request is sent from the client resolve a {@link TypeHierarchyItem type hierarchy item} for
+ * a give cursor location in the text document. The request would also allow to specify if the item should be resolved
+ * and whether sub- or supertypes are to be resolved.
+ */
+@Beta
+@SuppressWarnings("all")
+public class TypeHierarchyParams extends TextDocumentPositionParams {
+  /**
+   * The number of hierarchy levels to resolve. {@code 0} indicates no hierarchy level. It defaults to {@code 0}.
+   */
+  private int resolve;
+  
+  /**
+   * The direction of the type hierarchy resolution. If not defined, defaults to {@link TypeHierarchyDirection#Children Children}.
+   */
+  private TypeHierarchyDirection direction;
+  
+  /**
+   * The number of hierarchy levels to resolve. {@code 0} indicates no hierarchy level. It defaults to {@code 0}.
+   */
+  @Pure
+  public int getResolve() {
+    return this.resolve;
+  }
+  
+  /**
+   * The number of hierarchy levels to resolve. {@code 0} indicates no hierarchy level. It defaults to {@code 0}.
+   */
+  public void setResolve(final int resolve) {
+    this.resolve = resolve;
+  }
+  
+  /**
+   * The direction of the type hierarchy resolution. If not defined, defaults to {@link TypeHierarchyDirection#Children Children}.
+   */
+  @Pure
+  public TypeHierarchyDirection getDirection() {
+    return this.direction;
+  }
+  
+  /**
+   * The direction of the type hierarchy resolution. If not defined, defaults to {@link TypeHierarchyDirection#Children Children}.
+   */
+  public void setDirection(final TypeHierarchyDirection direction) {
+    this.direction = direction;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("resolve", this.resolve);
+    b.add("direction", this.direction);
+    b.add("textDocument", getTextDocument());
+    b.add("uri", getUri());
+    b.add("position", getPosition());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    TypeHierarchyParams other = (TypeHierarchyParams) obj;
+    if (other.resolve != this.resolve)
+      return false;
+    if (this.direction == null) {
+      if (other.direction != null)
+        return false;
+    } else if (!this.direction.equals(other.direction))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + this.resolve;
+    return prime * result + ((this.direction== null) ? 0 : this.direction.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/UniquenessLevel.java b/java/org/eclipse/lsp4j/UniquenessLevel.java
new file mode 100644
index 0000000..dfb258e
--- /dev/null
+++ b/java/org/eclipse/lsp4j/UniquenessLevel.java
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2020 TypeFox and others.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+package org.eclipse.lsp4j;
+
+/**
+ * Moniker uniqueness level to define scope of the moniker.
+ * 
+ * Since 3.16.0
+ */
+public final class UniquenessLevel {
+	private UniquenessLevel() {
+	}
+
+	/**
+	 * The moniker is only unique inside a document
+	 */
+	public static final String Document = "document";
+
+	/**
+	 * The moniker is unique inside a project for which a dump got created
+	 */
+	public static final String Project = "project";
+
+	/**
+	 * The moniker is unique inside the group to which a project belongs
+	 */
+	public static final String Group = "group";
+
+	/**
+	 * The moniker is unique inside the moniker scheme.
+	 */
+	public static final String Scheme = "scheme";
+
+	/**
+	 * The moniker is globally unique
+	 */
+	public static final String Global = "global";
+}
diff --git a/java/org/eclipse/lsp4j/Unregistration.java b/java/org/eclipse/lsp4j/Unregistration.java
new file mode 100644
index 0000000..6b7fa0b
--- /dev/null
+++ b/java/org/eclipse/lsp4j/Unregistration.java
@@ -0,0 +1,119 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * General parameters to unregister a capability.
+ */
+@SuppressWarnings("all")
+public class Unregistration {
+  /**
+   * The id used to unregister the request or notification. Usually an id
+   * provided during the register request.
+   */
+  @NonNull
+  private String id;
+  
+  /**
+   * The method / capability to unregister for.
+   */
+  @NonNull
+  private String method;
+  
+  public Unregistration() {
+  }
+  
+  public Unregistration(@NonNull final String id, @NonNull final String method) {
+    this.id = Preconditions.<String>checkNotNull(id, "id");
+    this.method = Preconditions.<String>checkNotNull(method, "method");
+  }
+  
+  /**
+   * The id used to unregister the request or notification. Usually an id
+   * provided during the register request.
+   */
+  @Pure
+  @NonNull
+  public String getId() {
+    return this.id;
+  }
+  
+  /**
+   * The id used to unregister the request or notification. Usually an id
+   * provided during the register request.
+   */
+  public void setId(@NonNull final String id) {
+    this.id = Preconditions.checkNotNull(id, "id");
+  }
+  
+  /**
+   * The method / capability to unregister for.
+   */
+  @Pure
+  @NonNull
+  public String getMethod() {
+    return this.method;
+  }
+  
+  /**
+   * The method / capability to unregister for.
+   */
+  public void setMethod(@NonNull final String method) {
+    this.method = Preconditions.checkNotNull(method, "method");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("id", this.id);
+    b.add("method", this.method);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    Unregistration other = (Unregistration) obj;
+    if (this.id == null) {
+      if (other.id != null)
+        return false;
+    } else if (!this.id.equals(other.id))
+      return false;
+    if (this.method == null) {
+      if (other.method != null)
+        return false;
+    } else if (!this.method.equals(other.method))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.id== null) ? 0 : this.id.hashCode());
+    return prime * result + ((this.method== null) ? 0 : this.method.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/UnregistrationParams.java b/java/org/eclipse/lsp4j/UnregistrationParams.java
new file mode 100644
index 0000000..aba3733
--- /dev/null
+++ b/java/org/eclipse/lsp4j/UnregistrationParams.java
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.lsp4j.Unregistration;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The client/unregisterCapability request is sent from the server to the client to unregister
+ * a previously registered capability.
+ */
+@SuppressWarnings("all")
+public class UnregistrationParams {
+  @NonNull
+  private List<Unregistration> unregisterations;
+  
+  public UnregistrationParams() {
+    this(new ArrayList<Unregistration>());
+  }
+  
+  public UnregistrationParams(@NonNull final List<Unregistration> unregisterations) {
+    this.unregisterations = Preconditions.<List<Unregistration>>checkNotNull(unregisterations, "unregisterations");
+  }
+  
+  @Pure
+  @NonNull
+  public List<Unregistration> getUnregisterations() {
+    return this.unregisterations;
+  }
+  
+  public void setUnregisterations(@NonNull final List<Unregistration> unregisterations) {
+    this.unregisterations = Preconditions.checkNotNull(unregisterations, "unregisterations");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("unregisterations", this.unregisterations);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    UnregistrationParams other = (UnregistrationParams) obj;
+    if (this.unregisterations == null) {
+      if (other.unregisterations != null)
+        return false;
+    } else if (!this.unregisterations.equals(other.unregisterations))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.unregisterations== null) ? 0 : this.unregisterations.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/VersionedTextDocumentIdentifier.java b/java/org/eclipse/lsp4j/VersionedTextDocumentIdentifier.java
new file mode 100644
index 0000000..d50e6b8
--- /dev/null
+++ b/java/org/eclipse/lsp4j/VersionedTextDocumentIdentifier.java
@@ -0,0 +1,106 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import com.google.gson.annotations.JsonAdapter;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.adapters.VersionedTextDocumentIdentifierTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * An identifier to denote a specific version of a text document. This information usually flows from the client to the server.
+ */
+@JsonAdapter(VersionedTextDocumentIdentifierTypeAdapter.Factory.class)
+@SuppressWarnings("all")
+public class VersionedTextDocumentIdentifier extends TextDocumentIdentifier {
+  /**
+   * The version number of this document. If a versioned text document identifier
+   * is sent from the server to the client and the file is not open in the editor
+   * (the server has not received an open notification before) the server can send
+   * `null` to indicate that the version is known and the content on disk is the
+   * truth (as specified with document content ownership).
+   */
+  private Integer version;
+  
+  public VersionedTextDocumentIdentifier() {
+  }
+  
+  public VersionedTextDocumentIdentifier(@NonNull final String uri, final Integer version) {
+    super(uri);
+    this.version = version;
+  }
+  
+  @Deprecated
+  public VersionedTextDocumentIdentifier(final Integer version) {
+    this.version = version;
+  }
+  
+  /**
+   * The version number of this document. If a versioned text document identifier
+   * is sent from the server to the client and the file is not open in the editor
+   * (the server has not received an open notification before) the server can send
+   * `null` to indicate that the version is known and the content on disk is the
+   * truth (as specified with document content ownership).
+   */
+  @Pure
+  public Integer getVersion() {
+    return this.version;
+  }
+  
+  /**
+   * The version number of this document. If a versioned text document identifier
+   * is sent from the server to the client and the file is not open in the editor
+   * (the server has not received an open notification before) the server can send
+   * `null` to indicate that the version is known and the content on disk is the
+   * truth (as specified with document content ownership).
+   */
+  public void setVersion(final Integer version) {
+    this.version = version;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("version", this.version);
+    b.add("uri", getUri());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    VersionedTextDocumentIdentifier other = (VersionedTextDocumentIdentifier) obj;
+    if (this.version == null) {
+      if (other.version != null)
+        return false;
+    } else if (!this.version.equals(other.version))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.version== null) ? 0 : this.version.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/WatchKind.java b/java/org/eclipse/lsp4j/WatchKind.java
new file mode 100644
index 0000000..46b51cf
--- /dev/null
+++ b/java/org/eclipse/lsp4j/WatchKind.java
@@ -0,0 +1,32 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j;
+
+public final class WatchKind {
+	private WatchKind() {}
+	
+	/**
+	 * Interested in create events.
+	 */
+	public static final int Create = 1;
+	
+	/**
+	 * Interested in change events
+	 */
+	public static final int Change = 2;
+	
+	/**
+	 * Interested in delete events
+	 */
+	public static final int Delete = 4;
+	
+}
diff --git a/java/org/eclipse/lsp4j/WillSaveTextDocumentParams.java b/java/org/eclipse/lsp4j/WillSaveTextDocumentParams.java
new file mode 100644
index 0000000..222b9fa
--- /dev/null
+++ b/java/org/eclipse/lsp4j/WillSaveTextDocumentParams.java
@@ -0,0 +1,115 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.TextDocumentSaveReason;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class WillSaveTextDocumentParams {
+  /**
+   * The document that will be saved.
+   */
+  @NonNull
+  private TextDocumentIdentifier textDocument;
+  
+  /**
+   * A reason why a text document is saved.
+   */
+  @NonNull
+  private TextDocumentSaveReason reason;
+  
+  public WillSaveTextDocumentParams() {
+  }
+  
+  public WillSaveTextDocumentParams(@NonNull final TextDocumentIdentifier textDocument, @NonNull final TextDocumentSaveReason reason) {
+    this.textDocument = Preconditions.<TextDocumentIdentifier>checkNotNull(textDocument, "textDocument");
+    this.reason = Preconditions.<TextDocumentSaveReason>checkNotNull(reason, "reason");
+  }
+  
+  /**
+   * The document that will be saved.
+   */
+  @Pure
+  @NonNull
+  public TextDocumentIdentifier getTextDocument() {
+    return this.textDocument;
+  }
+  
+  /**
+   * The document that will be saved.
+   */
+  public void setTextDocument(@NonNull final TextDocumentIdentifier textDocument) {
+    this.textDocument = Preconditions.checkNotNull(textDocument, "textDocument");
+  }
+  
+  /**
+   * A reason why a text document is saved.
+   */
+  @Pure
+  @NonNull
+  public TextDocumentSaveReason getReason() {
+    return this.reason;
+  }
+  
+  /**
+   * A reason why a text document is saved.
+   */
+  public void setReason(@NonNull final TextDocumentSaveReason reason) {
+    this.reason = Preconditions.checkNotNull(reason, "reason");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("textDocument", this.textDocument);
+    b.add("reason", this.reason);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    WillSaveTextDocumentParams other = (WillSaveTextDocumentParams) obj;
+    if (this.textDocument == null) {
+      if (other.textDocument != null)
+        return false;
+    } else if (!this.textDocument.equals(other.textDocument))
+      return false;
+    if (this.reason == null) {
+      if (other.reason != null)
+        return false;
+    } else if (!this.reason.equals(other.reason))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.textDocument== null) ? 0 : this.textDocument.hashCode());
+    return prime * result + ((this.reason== null) ? 0 : this.reason.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/WindowClientCapabilities.java b/java/org/eclipse/lsp4j/WindowClientCapabilities.java
new file mode 100644
index 0000000..1a8e739
--- /dev/null
+++ b/java/org/eclipse/lsp4j/WindowClientCapabilities.java
@@ -0,0 +1,152 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.ShowDocumentCapabilities;
+import org.eclipse.lsp4j.WindowShowMessageRequestCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Window specific client capabilities.
+ */
+@SuppressWarnings("all")
+public class WindowClientCapabilities {
+  /**
+   * Whether client supports handling progress notifications. If set servers are allowed to
+   * report in `workDoneProgress` property in the request specific server capabilities.
+   * <p>
+   * Since 3.15.0
+   */
+  private Boolean workDoneProgress;
+  
+  /**
+   * Capabilities specific to the showMessage request
+   * <p>
+   * Since 3.16.0
+   */
+  private WindowShowMessageRequestCapabilities showMessage;
+  
+  /**
+   * Client capabilities for the show document request.
+   * <p>
+   * Since 3.16.0
+   */
+  private ShowDocumentCapabilities showDocument;
+  
+  /**
+   * Whether client supports handling progress notifications. If set servers are allowed to
+   * report in `workDoneProgress` property in the request specific server capabilities.
+   * <p>
+   * Since 3.15.0
+   */
+  @Pure
+  public Boolean getWorkDoneProgress() {
+    return this.workDoneProgress;
+  }
+  
+  /**
+   * Whether client supports handling progress notifications. If set servers are allowed to
+   * report in `workDoneProgress` property in the request specific server capabilities.
+   * <p>
+   * Since 3.15.0
+   */
+  public void setWorkDoneProgress(final Boolean workDoneProgress) {
+    this.workDoneProgress = workDoneProgress;
+  }
+  
+  /**
+   * Capabilities specific to the showMessage request
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public WindowShowMessageRequestCapabilities getShowMessage() {
+    return this.showMessage;
+  }
+  
+  /**
+   * Capabilities specific to the showMessage request
+   * <p>
+   * Since 3.16.0
+   */
+  public void setShowMessage(final WindowShowMessageRequestCapabilities showMessage) {
+    this.showMessage = showMessage;
+  }
+  
+  /**
+   * Client capabilities for the show document request.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public ShowDocumentCapabilities getShowDocument() {
+    return this.showDocument;
+  }
+  
+  /**
+   * Client capabilities for the show document request.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setShowDocument(final ShowDocumentCapabilities showDocument) {
+    this.showDocument = showDocument;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneProgress", this.workDoneProgress);
+    b.add("showMessage", this.showMessage);
+    b.add("showDocument", this.showDocument);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    WindowClientCapabilities other = (WindowClientCapabilities) obj;
+    if (this.workDoneProgress == null) {
+      if (other.workDoneProgress != null)
+        return false;
+    } else if (!this.workDoneProgress.equals(other.workDoneProgress))
+      return false;
+    if (this.showMessage == null) {
+      if (other.showMessage != null)
+        return false;
+    } else if (!this.showMessage.equals(other.showMessage))
+      return false;
+    if (this.showDocument == null) {
+      if (other.showDocument != null)
+        return false;
+    } else if (!this.showDocument.equals(other.showDocument))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.workDoneProgress== null) ? 0 : this.workDoneProgress.hashCode());
+    result = prime * result + ((this.showMessage== null) ? 0 : this.showMessage.hashCode());
+    return prime * result + ((this.showDocument== null) ? 0 : this.showDocument.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/WindowShowMessageRequestActionItemCapabilities.java b/java/org/eclipse/lsp4j/WindowShowMessageRequestActionItemCapabilities.java
new file mode 100644
index 0000000..222963e
--- /dev/null
+++ b/java/org/eclipse/lsp4j/WindowShowMessageRequestActionItemCapabilities.java
@@ -0,0 +1,88 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to the {@link MessageActionItem} type of show message request.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class WindowShowMessageRequestActionItemCapabilities {
+  /**
+   * Whether the client supports additional attributes which
+   * are preserved and sent back to the server in the
+   * request's response.
+   */
+  private Boolean additionalPropertiesSupport;
+  
+  public WindowShowMessageRequestActionItemCapabilities() {
+  }
+  
+  public WindowShowMessageRequestActionItemCapabilities(final Boolean additionalPropertiesSupport) {
+    this.additionalPropertiesSupport = additionalPropertiesSupport;
+  }
+  
+  /**
+   * Whether the client supports additional attributes which
+   * are preserved and sent back to the server in the
+   * request's response.
+   */
+  @Pure
+  public Boolean getAdditionalPropertiesSupport() {
+    return this.additionalPropertiesSupport;
+  }
+  
+  /**
+   * Whether the client supports additional attributes which
+   * are preserved and sent back to the server in the
+   * request's response.
+   */
+  public void setAdditionalPropertiesSupport(final Boolean additionalPropertiesSupport) {
+    this.additionalPropertiesSupport = additionalPropertiesSupport;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("additionalPropertiesSupport", this.additionalPropertiesSupport);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    WindowShowMessageRequestActionItemCapabilities other = (WindowShowMessageRequestActionItemCapabilities) obj;
+    if (this.additionalPropertiesSupport == null) {
+      if (other.additionalPropertiesSupport != null)
+        return false;
+    } else if (!this.additionalPropertiesSupport.equals(other.additionalPropertiesSupport))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.additionalPropertiesSupport== null) ? 0 : this.additionalPropertiesSupport.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/WindowShowMessageRequestCapabilities.java b/java/org/eclipse/lsp4j/WindowShowMessageRequestCapabilities.java
new file mode 100644
index 0000000..116dca8
--- /dev/null
+++ b/java/org/eclipse/lsp4j/WindowShowMessageRequestCapabilities.java
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.WindowShowMessageRequestActionItemCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Show message request client capabilities
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class WindowShowMessageRequestCapabilities {
+  /**
+   * Capabilities specific to the {@link MessageActionItem} type.
+   */
+  private WindowShowMessageRequestActionItemCapabilities messageActionItem;
+  
+  public WindowShowMessageRequestCapabilities() {
+  }
+  
+  /**
+   * Capabilities specific to the {@link MessageActionItem} type.
+   */
+  @Pure
+  public WindowShowMessageRequestActionItemCapabilities getMessageActionItem() {
+    return this.messageActionItem;
+  }
+  
+  /**
+   * Capabilities specific to the {@link MessageActionItem} type.
+   */
+  public void setMessageActionItem(final WindowShowMessageRequestActionItemCapabilities messageActionItem) {
+    this.messageActionItem = messageActionItem;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("messageActionItem", this.messageActionItem);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    WindowShowMessageRequestCapabilities other = (WindowShowMessageRequestCapabilities) obj;
+    if (this.messageActionItem == null) {
+      if (other.messageActionItem != null)
+        return false;
+    } else if (!this.messageActionItem.equals(other.messageActionItem))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.messageActionItem== null) ? 0 : this.messageActionItem.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/WorkDoneProgressAndPartialResultParams.java b/java/org/eclipse/lsp4j/WorkDoneProgressAndPartialResultParams.java
new file mode 100644
index 0000000..f800e13
--- /dev/null
+++ b/java/org/eclipse/lsp4j/WorkDoneProgressAndPartialResultParams.java
@@ -0,0 +1,145 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.PartialResultParams;
+import org.eclipse.lsp4j.WorkDoneProgressParams;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Abstract class which implements work done progress and partial result request parameter.
+ * It is not present in protocol specification, so it's just "dry" class.
+ * <p>
+ * Since 3.15.0
+ */
+@SuppressWarnings("all")
+public abstract class WorkDoneProgressAndPartialResultParams implements WorkDoneProgressParams, PartialResultParams {
+  /**
+   * An optional token that a server can use to report work done progress.
+   */
+  private Either<String, Integer> workDoneToken;
+  
+  /**
+   * An optional token that a server can use to report partial results (e.g. streaming) to
+   * the client.
+   */
+  private Either<String, Integer> partialResultToken;
+  
+  /**
+   * An optional token that a server can use to report work done progress.
+   */
+  @Pure
+  @Override
+  public Either<String, Integer> getWorkDoneToken() {
+    return this.workDoneToken;
+  }
+  
+  /**
+   * An optional token that a server can use to report work done progress.
+   */
+  public void setWorkDoneToken(final Either<String, Integer> workDoneToken) {
+    this.workDoneToken = workDoneToken;
+  }
+  
+  public void setWorkDoneToken(final String workDoneToken) {
+    if (workDoneToken == null) {
+      this.workDoneToken = null;
+      return;
+    }
+    this.workDoneToken = Either.forLeft(workDoneToken);
+  }
+  
+  public void setWorkDoneToken(final Integer workDoneToken) {
+    if (workDoneToken == null) {
+      this.workDoneToken = null;
+      return;
+    }
+    this.workDoneToken = Either.forRight(workDoneToken);
+  }
+  
+  /**
+   * An optional token that a server can use to report partial results (e.g. streaming) to
+   * the client.
+   */
+  @Pure
+  @Override
+  public Either<String, Integer> getPartialResultToken() {
+    return this.partialResultToken;
+  }
+  
+  /**
+   * An optional token that a server can use to report partial results (e.g. streaming) to
+   * the client.
+   */
+  public void setPartialResultToken(final Either<String, Integer> partialResultToken) {
+    this.partialResultToken = partialResultToken;
+  }
+  
+  public void setPartialResultToken(final String partialResultToken) {
+    if (partialResultToken == null) {
+      this.partialResultToken = null;
+      return;
+    }
+    this.partialResultToken = Either.forLeft(partialResultToken);
+  }
+  
+  public void setPartialResultToken(final Integer partialResultToken) {
+    if (partialResultToken == null) {
+      this.partialResultToken = null;
+      return;
+    }
+    this.partialResultToken = Either.forRight(partialResultToken);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneToken", this.workDoneToken);
+    b.add("partialResultToken", this.partialResultToken);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    WorkDoneProgressAndPartialResultParams other = (WorkDoneProgressAndPartialResultParams) obj;
+    if (this.workDoneToken == null) {
+      if (other.workDoneToken != null)
+        return false;
+    } else if (!this.workDoneToken.equals(other.workDoneToken))
+      return false;
+    if (this.partialResultToken == null) {
+      if (other.partialResultToken != null)
+        return false;
+    } else if (!this.partialResultToken.equals(other.partialResultToken))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.workDoneToken== null) ? 0 : this.workDoneToken.hashCode());
+    return prime * result + ((this.partialResultToken== null) ? 0 : this.partialResultToken.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/WorkDoneProgressBegin.java b/java/org/eclipse/lsp4j/WorkDoneProgressBegin.java
new file mode 100644
index 0000000..5294d70
--- /dev/null
+++ b/java/org/eclipse/lsp4j/WorkDoneProgressBegin.java
@@ -0,0 +1,214 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.WorkDoneProgressKind;
+import org.eclipse.lsp4j.WorkDoneProgressNotification;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The $/progress notification payload to start progress reporting.
+ * <p>
+ * Since 3.15.0
+ */
+@SuppressWarnings("all")
+public class WorkDoneProgressBegin implements WorkDoneProgressNotification {
+  /**
+   * Always return begin
+   */
+  @Override
+  public WorkDoneProgressKind getKind() {
+    return WorkDoneProgressKind.begin;
+  }
+  
+  /**
+   * Mandatory title of the progress operation. Used to briefly inform about
+   * the kind of operation being performed.
+   * <p>
+   * Examples: "Indexing" or "Linking dependencies".
+   */
+  @NonNull
+  private String title;
+  
+  /**
+   * Controls if a cancel button should show to allow the user to cancel the
+   * long running operation. Clients that don't support cancellation are allowed
+   * to ignore the setting.
+   */
+  private Boolean cancellable;
+  
+  /**
+   * Optional, more detailed associated progress message. Contains
+   * complementary information to the {@link #title}.
+   * <p>
+   * Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
+   * If unset, the previous progress message (if any) is still valid.
+   */
+  private String message;
+  
+  /**
+   * Optional progress percentage to display (value 100 is considered 100%).
+   * If not provided infinite progress is assumed and clients are allowed
+   * to ignore the `percentage` value in subsequent in report notifications.
+   * <p>
+   * The value should be steadily rising. Clients are free to ignore values
+   * that are not following this rule.
+   */
+  private Integer percentage;
+  
+  /**
+   * Mandatory title of the progress operation. Used to briefly inform about
+   * the kind of operation being performed.
+   * <p>
+   * Examples: "Indexing" or "Linking dependencies".
+   */
+  @Pure
+  @NonNull
+  public String getTitle() {
+    return this.title;
+  }
+  
+  /**
+   * Mandatory title of the progress operation. Used to briefly inform about
+   * the kind of operation being performed.
+   * <p>
+   * Examples: "Indexing" or "Linking dependencies".
+   */
+  public void setTitle(@NonNull final String title) {
+    this.title = Preconditions.checkNotNull(title, "title");
+  }
+  
+  /**
+   * Controls if a cancel button should show to allow the user to cancel the
+   * long running operation. Clients that don't support cancellation are allowed
+   * to ignore the setting.
+   */
+  @Pure
+  public Boolean getCancellable() {
+    return this.cancellable;
+  }
+  
+  /**
+   * Controls if a cancel button should show to allow the user to cancel the
+   * long running operation. Clients that don't support cancellation are allowed
+   * to ignore the setting.
+   */
+  public void setCancellable(final Boolean cancellable) {
+    this.cancellable = cancellable;
+  }
+  
+  /**
+   * Optional, more detailed associated progress message. Contains
+   * complementary information to the {@link #title}.
+   * <p>
+   * Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
+   * If unset, the previous progress message (if any) is still valid.
+   */
+  @Pure
+  public String getMessage() {
+    return this.message;
+  }
+  
+  /**
+   * Optional, more detailed associated progress message. Contains
+   * complementary information to the {@link #title}.
+   * <p>
+   * Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
+   * If unset, the previous progress message (if any) is still valid.
+   */
+  public void setMessage(final String message) {
+    this.message = message;
+  }
+  
+  /**
+   * Optional progress percentage to display (value 100 is considered 100%).
+   * If not provided infinite progress is assumed and clients are allowed
+   * to ignore the `percentage` value in subsequent in report notifications.
+   * <p>
+   * The value should be steadily rising. Clients are free to ignore values
+   * that are not following this rule.
+   */
+  @Pure
+  public Integer getPercentage() {
+    return this.percentage;
+  }
+  
+  /**
+   * Optional progress percentage to display (value 100 is considered 100%).
+   * If not provided infinite progress is assumed and clients are allowed
+   * to ignore the `percentage` value in subsequent in report notifications.
+   * <p>
+   * The value should be steadily rising. Clients are free to ignore values
+   * that are not following this rule.
+   */
+  public void setPercentage(final Integer percentage) {
+    this.percentage = percentage;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("title", this.title);
+    b.add("cancellable", this.cancellable);
+    b.add("message", this.message);
+    b.add("percentage", this.percentage);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    WorkDoneProgressBegin other = (WorkDoneProgressBegin) obj;
+    if (this.title == null) {
+      if (other.title != null)
+        return false;
+    } else if (!this.title.equals(other.title))
+      return false;
+    if (this.cancellable == null) {
+      if (other.cancellable != null)
+        return false;
+    } else if (!this.cancellable.equals(other.cancellable))
+      return false;
+    if (this.message == null) {
+      if (other.message != null)
+        return false;
+    } else if (!this.message.equals(other.message))
+      return false;
+    if (this.percentage == null) {
+      if (other.percentage != null)
+        return false;
+    } else if (!this.percentage.equals(other.percentage))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.title== null) ? 0 : this.title.hashCode());
+    result = prime * result + ((this.cancellable== null) ? 0 : this.cancellable.hashCode());
+    result = prime * result + ((this.message== null) ? 0 : this.message.hashCode());
+    return prime * result + ((this.percentage== null) ? 0 : this.percentage.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/WorkDoneProgressCancelParams.java b/java/org/eclipse/lsp4j/WorkDoneProgressCancelParams.java
new file mode 100644
index 0000000..332e540
--- /dev/null
+++ b/java/org/eclipse/lsp4j/WorkDoneProgressCancelParams.java
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The {@code window/workDoneProgress/cancel} notification is sent from the client to the server to cancel a progress initiated on the server side using the
+ * {@code window/workDoneProgress/create}.
+ */
+@SuppressWarnings("all")
+public class WorkDoneProgressCancelParams {
+  /**
+   * The token to be used to report progress.
+   */
+  @NonNull
+  private Either<String, Integer> token;
+  
+  public WorkDoneProgressCancelParams() {
+  }
+  
+  public WorkDoneProgressCancelParams(@NonNull final Either<String, Integer> token) {
+    this.token = Preconditions.<Either<String, Integer>>checkNotNull(token, "token");
+  }
+  
+  /**
+   * The token to be used to report progress.
+   */
+  @Pure
+  @NonNull
+  public Either<String, Integer> getToken() {
+    return this.token;
+  }
+  
+  /**
+   * The token to be used to report progress.
+   */
+  public void setToken(@NonNull final Either<String, Integer> token) {
+    this.token = Preconditions.checkNotNull(token, "token");
+  }
+  
+  public void setToken(final String token) {
+    if (token == null) {
+      Preconditions.checkNotNull(token, "token");
+      this.token = null;
+      return;
+    }
+    this.token = Either.forLeft(token);
+  }
+  
+  public void setToken(final Integer token) {
+    if (token == null) {
+      Preconditions.checkNotNull(token, "token");
+      this.token = null;
+      return;
+    }
+    this.token = Either.forRight(token);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("token", this.token);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    WorkDoneProgressCancelParams other = (WorkDoneProgressCancelParams) obj;
+    if (this.token == null) {
+      if (other.token != null)
+        return false;
+    } else if (!this.token.equals(other.token))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.token== null) ? 0 : this.token.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/WorkDoneProgressCreateParams.java b/java/org/eclipse/lsp4j/WorkDoneProgressCreateParams.java
new file mode 100644
index 0000000..ce5c79f
--- /dev/null
+++ b/java/org/eclipse/lsp4j/WorkDoneProgressCreateParams.java
@@ -0,0 +1,103 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The {@code window/workDoneProgress/create} request is sent from the server to the client to ask the client to create a work done progress.
+ */
+@SuppressWarnings("all")
+public class WorkDoneProgressCreateParams {
+  /**
+   * The token to be used to report progress.
+   */
+  @NonNull
+  private Either<String, Integer> token;
+  
+  public WorkDoneProgressCreateParams() {
+  }
+  
+  public WorkDoneProgressCreateParams(@NonNull final Either<String, Integer> token) {
+    this.token = Preconditions.<Either<String, Integer>>checkNotNull(token, "token");
+  }
+  
+  /**
+   * The token to be used to report progress.
+   */
+  @Pure
+  @NonNull
+  public Either<String, Integer> getToken() {
+    return this.token;
+  }
+  
+  /**
+   * The token to be used to report progress.
+   */
+  public void setToken(@NonNull final Either<String, Integer> token) {
+    this.token = Preconditions.checkNotNull(token, "token");
+  }
+  
+  public void setToken(final String token) {
+    if (token == null) {
+      Preconditions.checkNotNull(token, "token");
+      this.token = null;
+      return;
+    }
+    this.token = Either.forLeft(token);
+  }
+  
+  public void setToken(final Integer token) {
+    if (token == null) {
+      Preconditions.checkNotNull(token, "token");
+      this.token = null;
+      return;
+    }
+    this.token = Either.forRight(token);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("token", this.token);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    WorkDoneProgressCreateParams other = (WorkDoneProgressCreateParams) obj;
+    if (this.token == null) {
+      if (other.token != null)
+        return false;
+    } else if (!this.token.equals(other.token))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.token== null) ? 0 : this.token.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/WorkDoneProgressEnd.java b/java/org/eclipse/lsp4j/WorkDoneProgressEnd.java
new file mode 100644
index 0000000..5a8ea02
--- /dev/null
+++ b/java/org/eclipse/lsp4j/WorkDoneProgressEnd.java
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.WorkDoneProgressKind;
+import org.eclipse.lsp4j.WorkDoneProgressNotification;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The notification payload about progress reporting.
+ * Signaling the end of a progress reporting is done using the following payload:
+ * <p>
+ * Since 3.15.0
+ */
+@SuppressWarnings("all")
+public class WorkDoneProgressEnd implements WorkDoneProgressNotification {
+  /**
+   * Always return end
+   */
+  @Override
+  public WorkDoneProgressKind getKind() {
+    return WorkDoneProgressKind.end;
+  }
+  
+  /**
+   * Optional, a final message indicating to for example indicate the outcome
+   * of the operation.
+   */
+  private String message;
+  
+  /**
+   * Optional, a final message indicating to for example indicate the outcome
+   * of the operation.
+   */
+  @Pure
+  public String getMessage() {
+    return this.message;
+  }
+  
+  /**
+   * Optional, a final message indicating to for example indicate the outcome
+   * of the operation.
+   */
+  public void setMessage(final String message) {
+    this.message = message;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("message", this.message);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    WorkDoneProgressEnd other = (WorkDoneProgressEnd) obj;
+    if (this.message == null) {
+      if (other.message != null)
+        return false;
+    } else if (!this.message.equals(other.message))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.message== null) ? 0 : this.message.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/WorkDoneProgressKind.java b/java/org/eclipse/lsp4j/WorkDoneProgressKind.java
new file mode 100644
index 0000000..171eb6c
--- /dev/null
+++ b/java/org/eclipse/lsp4j/WorkDoneProgressKind.java
@@ -0,0 +1,17 @@
+/******************************************************************************
+ * Copyright (c) 2020 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j;
+
+public enum WorkDoneProgressKind {
+	begin, report, end;
+
+}
diff --git a/java/org/eclipse/lsp4j/WorkDoneProgressNotification.java b/java/org/eclipse/lsp4j/WorkDoneProgressNotification.java
new file mode 100644
index 0000000..6e528b9
--- /dev/null
+++ b/java/org/eclipse/lsp4j/WorkDoneProgressNotification.java
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.WorkDoneProgressKind;
+
+/**
+ * The $/progress notification payload interface.
+ * <p>
+ * Since 3.15.0
+ */
+@SuppressWarnings("all")
+public interface WorkDoneProgressNotification {
+  WorkDoneProgressKind getKind();
+}
diff --git a/java/org/eclipse/lsp4j/WorkDoneProgressOptions.java b/java/org/eclipse/lsp4j/WorkDoneProgressOptions.java
new file mode 100644
index 0000000..e6daaef
--- /dev/null
+++ b/java/org/eclipse/lsp4j/WorkDoneProgressOptions.java
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+/**
+ * Options to signal work done progress support in server capabilities.
+ * <p>
+ * Since 3.15.0
+ */
+@SuppressWarnings("all")
+public interface WorkDoneProgressOptions {
+  Boolean getWorkDoneProgress();
+  
+  void setWorkDoneProgress(final Boolean workDoneProgress);
+}
diff --git a/java/org/eclipse/lsp4j/WorkDoneProgressParams.java b/java/org/eclipse/lsp4j/WorkDoneProgressParams.java
new file mode 100644
index 0000000..89c19c2
--- /dev/null
+++ b/java/org/eclipse/lsp4j/WorkDoneProgressParams.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+
+/**
+ * A parameter literal used to pass a work done progress token.
+ * <p>
+ * Since 3.15.0
+ */
+@SuppressWarnings("all")
+public interface WorkDoneProgressParams {
+  /**
+   * An optional token that a server can use to report work done progress.
+   */
+  Either<String, Integer> getWorkDoneToken();
+  
+  /**
+   * An optional token that a server can use to report work done progress.
+   */
+  void setWorkDoneToken(final Either<String, Integer> token);
+}
diff --git a/java/org/eclipse/lsp4j/WorkDoneProgressReport.java b/java/org/eclipse/lsp4j/WorkDoneProgressReport.java
new file mode 100644
index 0000000..3ce8eb2
--- /dev/null
+++ b/java/org/eclipse/lsp4j/WorkDoneProgressReport.java
@@ -0,0 +1,180 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.WorkDoneProgressKind;
+import org.eclipse.lsp4j.WorkDoneProgressNotification;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The notification payload about progress reporting.
+ * <p>
+ * Since 3.15.0
+ */
+@SuppressWarnings("all")
+public class WorkDoneProgressReport implements WorkDoneProgressNotification {
+  /**
+   * Always return report
+   */
+  @Override
+  public WorkDoneProgressKind getKind() {
+    return WorkDoneProgressKind.report;
+  }
+  
+  /**
+   * Controls enablement state of a cancel button. This property is only valid if a cancel
+   * button got requested in the {@link WorkDoneProgressBegin} payload.
+   * <p>
+   * Clients that don't support cancellation or don't support control the button's
+   * enablement state are allowed to ignore the setting.
+   */
+  private Boolean cancellable;
+  
+  /**
+   * Optional, more detailed associated progress message. Contains
+   * complementary information to the {@link WorkDoneProgressBegin#title}.
+   * <p>
+   * Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
+   * If unset, the previous progress message (if any) is still valid.
+   */
+  private String message;
+  
+  /**
+   * Optional progress percentage to display (value 100 is considered 100%).
+   * If not provided infinite progress is assumed and clients are allowed
+   * to ignore the `percentage` value in subsequent in report notifications.
+   * <p>
+   * The value should be steadily rising. Clients are free to ignore values
+   * that are not following this rule.
+   */
+  private Integer percentage;
+  
+  /**
+   * Controls enablement state of a cancel button. This property is only valid if a cancel
+   * button got requested in the {@link WorkDoneProgressBegin} payload.
+   * <p>
+   * Clients that don't support cancellation or don't support control the button's
+   * enablement state are allowed to ignore the setting.
+   */
+  @Pure
+  public Boolean getCancellable() {
+    return this.cancellable;
+  }
+  
+  /**
+   * Controls enablement state of a cancel button. This property is only valid if a cancel
+   * button got requested in the {@link WorkDoneProgressBegin} payload.
+   * <p>
+   * Clients that don't support cancellation or don't support control the button's
+   * enablement state are allowed to ignore the setting.
+   */
+  public void setCancellable(final Boolean cancellable) {
+    this.cancellable = cancellable;
+  }
+  
+  /**
+   * Optional, more detailed associated progress message. Contains
+   * complementary information to the {@link WorkDoneProgressBegin#title}.
+   * <p>
+   * Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
+   * If unset, the previous progress message (if any) is still valid.
+   */
+  @Pure
+  public String getMessage() {
+    return this.message;
+  }
+  
+  /**
+   * Optional, more detailed associated progress message. Contains
+   * complementary information to the {@link WorkDoneProgressBegin#title}.
+   * <p>
+   * Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
+   * If unset, the previous progress message (if any) is still valid.
+   */
+  public void setMessage(final String message) {
+    this.message = message;
+  }
+  
+  /**
+   * Optional progress percentage to display (value 100 is considered 100%).
+   * If not provided infinite progress is assumed and clients are allowed
+   * to ignore the `percentage` value in subsequent in report notifications.
+   * <p>
+   * The value should be steadily rising. Clients are free to ignore values
+   * that are not following this rule.
+   */
+  @Pure
+  public Integer getPercentage() {
+    return this.percentage;
+  }
+  
+  /**
+   * Optional progress percentage to display (value 100 is considered 100%).
+   * If not provided infinite progress is assumed and clients are allowed
+   * to ignore the `percentage` value in subsequent in report notifications.
+   * <p>
+   * The value should be steadily rising. Clients are free to ignore values
+   * that are not following this rule.
+   */
+  public void setPercentage(final Integer percentage) {
+    this.percentage = percentage;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("cancellable", this.cancellable);
+    b.add("message", this.message);
+    b.add("percentage", this.percentage);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    WorkDoneProgressReport other = (WorkDoneProgressReport) obj;
+    if (this.cancellable == null) {
+      if (other.cancellable != null)
+        return false;
+    } else if (!this.cancellable.equals(other.cancellable))
+      return false;
+    if (this.message == null) {
+      if (other.message != null)
+        return false;
+    } else if (!this.message.equals(other.message))
+      return false;
+    if (this.percentage == null) {
+      if (other.percentage != null)
+        return false;
+    } else if (!this.percentage.equals(other.percentage))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.cancellable== null) ? 0 : this.cancellable.hashCode());
+    result = prime * result + ((this.message== null) ? 0 : this.message.hashCode());
+    return prime * result + ((this.percentage== null) ? 0 : this.percentage.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/WorkspaceClientCapabilities.java b/java/org/eclipse/lsp4j/WorkspaceClientCapabilities.java
new file mode 100644
index 0000000..f5655d9
--- /dev/null
+++ b/java/org/eclipse/lsp4j/WorkspaceClientCapabilities.java
@@ -0,0 +1,392 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.CodeLensWorkspaceCapabilities;
+import org.eclipse.lsp4j.DidChangeConfigurationCapabilities;
+import org.eclipse.lsp4j.DidChangeWatchedFilesCapabilities;
+import org.eclipse.lsp4j.ExecuteCommandCapabilities;
+import org.eclipse.lsp4j.FileOperationsWorkspaceCapabilities;
+import org.eclipse.lsp4j.SemanticTokensWorkspaceCapabilities;
+import org.eclipse.lsp4j.SymbolCapabilities;
+import org.eclipse.lsp4j.WorkspaceEditCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Workspace specific client capabilities.
+ */
+@SuppressWarnings("all")
+public class WorkspaceClientCapabilities {
+  /**
+   * The client supports applying batch edits to the workspace by supporting
+   * the request 'workspace/applyEdit'.
+   */
+  private Boolean applyEdit;
+  
+  /**
+   * Capabilities specific to {@link WorkspaceEdit}s
+   */
+  private WorkspaceEditCapabilities workspaceEdit;
+  
+  /**
+   * Capabilities specific to the `workspace/didChangeConfiguration` notification.
+   */
+  private DidChangeConfigurationCapabilities didChangeConfiguration;
+  
+  /**
+   * Capabilities specific to the `workspace/didChangeWatchedFiles` notification.
+   */
+  private DidChangeWatchedFilesCapabilities didChangeWatchedFiles;
+  
+  /**
+   * Capabilities specific to the `workspace/symbol` request.
+   */
+  private SymbolCapabilities symbol;
+  
+  /**
+   * Capabilities specific to the `workspace/executeCommand` request.
+   */
+  private ExecuteCommandCapabilities executeCommand;
+  
+  /**
+   * The client has support for workspace folders.
+   * <p>
+   * Since 3.6.0
+   */
+  private Boolean workspaceFolders;
+  
+  /**
+   * The client supports `workspace/configuration` requests.
+   * <p>
+   * Since 3.6.0
+   */
+  private Boolean configuration;
+  
+  /**
+   * Capabilities specific to the semantic token requests scoped to the
+   * workspace.
+   * <p>
+   * Since 3.16.0
+   */
+  private SemanticTokensWorkspaceCapabilities semanticTokens;
+  
+  /**
+   * Capabilities specific to the code lens requests scoped to the
+   * workspace.
+   * <p>
+   * Since 3.16.0
+   */
+  private CodeLensWorkspaceCapabilities codeLens;
+  
+  /**
+   * The client has support for file requests/notifications.
+   * <p>
+   * Since 3.16.0
+   */
+  private FileOperationsWorkspaceCapabilities fileOperations;
+  
+  /**
+   * The client supports applying batch edits to the workspace by supporting
+   * the request 'workspace/applyEdit'.
+   */
+  @Pure
+  public Boolean getApplyEdit() {
+    return this.applyEdit;
+  }
+  
+  /**
+   * The client supports applying batch edits to the workspace by supporting
+   * the request 'workspace/applyEdit'.
+   */
+  public void setApplyEdit(final Boolean applyEdit) {
+    this.applyEdit = applyEdit;
+  }
+  
+  /**
+   * Capabilities specific to {@link WorkspaceEdit}s
+   */
+  @Pure
+  public WorkspaceEditCapabilities getWorkspaceEdit() {
+    return this.workspaceEdit;
+  }
+  
+  /**
+   * Capabilities specific to {@link WorkspaceEdit}s
+   */
+  public void setWorkspaceEdit(final WorkspaceEditCapabilities workspaceEdit) {
+    this.workspaceEdit = workspaceEdit;
+  }
+  
+  /**
+   * Capabilities specific to the `workspace/didChangeConfiguration` notification.
+   */
+  @Pure
+  public DidChangeConfigurationCapabilities getDidChangeConfiguration() {
+    return this.didChangeConfiguration;
+  }
+  
+  /**
+   * Capabilities specific to the `workspace/didChangeConfiguration` notification.
+   */
+  public void setDidChangeConfiguration(final DidChangeConfigurationCapabilities didChangeConfiguration) {
+    this.didChangeConfiguration = didChangeConfiguration;
+  }
+  
+  /**
+   * Capabilities specific to the `workspace/didChangeWatchedFiles` notification.
+   */
+  @Pure
+  public DidChangeWatchedFilesCapabilities getDidChangeWatchedFiles() {
+    return this.didChangeWatchedFiles;
+  }
+  
+  /**
+   * Capabilities specific to the `workspace/didChangeWatchedFiles` notification.
+   */
+  public void setDidChangeWatchedFiles(final DidChangeWatchedFilesCapabilities didChangeWatchedFiles) {
+    this.didChangeWatchedFiles = didChangeWatchedFiles;
+  }
+  
+  /**
+   * Capabilities specific to the `workspace/symbol` request.
+   */
+  @Pure
+  public SymbolCapabilities getSymbol() {
+    return this.symbol;
+  }
+  
+  /**
+   * Capabilities specific to the `workspace/symbol` request.
+   */
+  public void setSymbol(final SymbolCapabilities symbol) {
+    this.symbol = symbol;
+  }
+  
+  /**
+   * Capabilities specific to the `workspace/executeCommand` request.
+   */
+  @Pure
+  public ExecuteCommandCapabilities getExecuteCommand() {
+    return this.executeCommand;
+  }
+  
+  /**
+   * Capabilities specific to the `workspace/executeCommand` request.
+   */
+  public void setExecuteCommand(final ExecuteCommandCapabilities executeCommand) {
+    this.executeCommand = executeCommand;
+  }
+  
+  /**
+   * The client has support for workspace folders.
+   * <p>
+   * Since 3.6.0
+   */
+  @Pure
+  public Boolean getWorkspaceFolders() {
+    return this.workspaceFolders;
+  }
+  
+  /**
+   * The client has support for workspace folders.
+   * <p>
+   * Since 3.6.0
+   */
+  public void setWorkspaceFolders(final Boolean workspaceFolders) {
+    this.workspaceFolders = workspaceFolders;
+  }
+  
+  /**
+   * The client supports `workspace/configuration` requests.
+   * <p>
+   * Since 3.6.0
+   */
+  @Pure
+  public Boolean getConfiguration() {
+    return this.configuration;
+  }
+  
+  /**
+   * The client supports `workspace/configuration` requests.
+   * <p>
+   * Since 3.6.0
+   */
+  public void setConfiguration(final Boolean configuration) {
+    this.configuration = configuration;
+  }
+  
+  /**
+   * Capabilities specific to the semantic token requests scoped to the
+   * workspace.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public SemanticTokensWorkspaceCapabilities getSemanticTokens() {
+    return this.semanticTokens;
+  }
+  
+  /**
+   * Capabilities specific to the semantic token requests scoped to the
+   * workspace.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setSemanticTokens(final SemanticTokensWorkspaceCapabilities semanticTokens) {
+    this.semanticTokens = semanticTokens;
+  }
+  
+  /**
+   * Capabilities specific to the code lens requests scoped to the
+   * workspace.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public CodeLensWorkspaceCapabilities getCodeLens() {
+    return this.codeLens;
+  }
+  
+  /**
+   * Capabilities specific to the code lens requests scoped to the
+   * workspace.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setCodeLens(final CodeLensWorkspaceCapabilities codeLens) {
+    this.codeLens = codeLens;
+  }
+  
+  /**
+   * The client has support for file requests/notifications.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public FileOperationsWorkspaceCapabilities getFileOperations() {
+    return this.fileOperations;
+  }
+  
+  /**
+   * The client has support for file requests/notifications.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setFileOperations(final FileOperationsWorkspaceCapabilities fileOperations) {
+    this.fileOperations = fileOperations;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("applyEdit", this.applyEdit);
+    b.add("workspaceEdit", this.workspaceEdit);
+    b.add("didChangeConfiguration", this.didChangeConfiguration);
+    b.add("didChangeWatchedFiles", this.didChangeWatchedFiles);
+    b.add("symbol", this.symbol);
+    b.add("executeCommand", this.executeCommand);
+    b.add("workspaceFolders", this.workspaceFolders);
+    b.add("configuration", this.configuration);
+    b.add("semanticTokens", this.semanticTokens);
+    b.add("codeLens", this.codeLens);
+    b.add("fileOperations", this.fileOperations);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    WorkspaceClientCapabilities other = (WorkspaceClientCapabilities) obj;
+    if (this.applyEdit == null) {
+      if (other.applyEdit != null)
+        return false;
+    } else if (!this.applyEdit.equals(other.applyEdit))
+      return false;
+    if (this.workspaceEdit == null) {
+      if (other.workspaceEdit != null)
+        return false;
+    } else if (!this.workspaceEdit.equals(other.workspaceEdit))
+      return false;
+    if (this.didChangeConfiguration == null) {
+      if (other.didChangeConfiguration != null)
+        return false;
+    } else if (!this.didChangeConfiguration.equals(other.didChangeConfiguration))
+      return false;
+    if (this.didChangeWatchedFiles == null) {
+      if (other.didChangeWatchedFiles != null)
+        return false;
+    } else if (!this.didChangeWatchedFiles.equals(other.didChangeWatchedFiles))
+      return false;
+    if (this.symbol == null) {
+      if (other.symbol != null)
+        return false;
+    } else if (!this.symbol.equals(other.symbol))
+      return false;
+    if (this.executeCommand == null) {
+      if (other.executeCommand != null)
+        return false;
+    } else if (!this.executeCommand.equals(other.executeCommand))
+      return false;
+    if (this.workspaceFolders == null) {
+      if (other.workspaceFolders != null)
+        return false;
+    } else if (!this.workspaceFolders.equals(other.workspaceFolders))
+      return false;
+    if (this.configuration == null) {
+      if (other.configuration != null)
+        return false;
+    } else if (!this.configuration.equals(other.configuration))
+      return false;
+    if (this.semanticTokens == null) {
+      if (other.semanticTokens != null)
+        return false;
+    } else if (!this.semanticTokens.equals(other.semanticTokens))
+      return false;
+    if (this.codeLens == null) {
+      if (other.codeLens != null)
+        return false;
+    } else if (!this.codeLens.equals(other.codeLens))
+      return false;
+    if (this.fileOperations == null) {
+      if (other.fileOperations != null)
+        return false;
+    } else if (!this.fileOperations.equals(other.fileOperations))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.applyEdit== null) ? 0 : this.applyEdit.hashCode());
+    result = prime * result + ((this.workspaceEdit== null) ? 0 : this.workspaceEdit.hashCode());
+    result = prime * result + ((this.didChangeConfiguration== null) ? 0 : this.didChangeConfiguration.hashCode());
+    result = prime * result + ((this.didChangeWatchedFiles== null) ? 0 : this.didChangeWatchedFiles.hashCode());
+    result = prime * result + ((this.symbol== null) ? 0 : this.symbol.hashCode());
+    result = prime * result + ((this.executeCommand== null) ? 0 : this.executeCommand.hashCode());
+    result = prime * result + ((this.workspaceFolders== null) ? 0 : this.workspaceFolders.hashCode());
+    result = prime * result + ((this.configuration== null) ? 0 : this.configuration.hashCode());
+    result = prime * result + ((this.semanticTokens== null) ? 0 : this.semanticTokens.hashCode());
+    result = prime * result + ((this.codeLens== null) ? 0 : this.codeLens.hashCode());
+    return prime * result + ((this.fileOperations== null) ? 0 : this.fileOperations.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/WorkspaceEdit.java b/java/org/eclipse/lsp4j/WorkspaceEdit.java
new file mode 100644
index 0000000..39984e6
--- /dev/null
+++ b/java/org/eclipse/lsp4j/WorkspaceEdit.java
@@ -0,0 +1,263 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import com.google.common.annotations.Beta;
+import com.google.gson.annotations.JsonAdapter;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import org.eclipse.lsp4j.ChangeAnnotation;
+import org.eclipse.lsp4j.ResourceChange;
+import org.eclipse.lsp4j.ResourceOperation;
+import org.eclipse.lsp4j.TextDocumentEdit;
+import org.eclipse.lsp4j.TextEdit;
+import org.eclipse.lsp4j.adapters.DocumentChangeListAdapter;
+import org.eclipse.lsp4j.adapters.ResourceChangeListAdapter;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A workspace edit represents changes to many resources managed in the workspace.
+ * The edit should either provide {@link #changes} or {@link #documentChanges}.
+ * If documentChanges are present they are preferred over changes
+ * if the client can handle versioned document edits.
+ */
+@SuppressWarnings("all")
+public class WorkspaceEdit {
+  /**
+   * Holds changes to existing resources.
+   */
+  private Map<String, List<TextEdit>> changes;
+  
+  /**
+   * Depending on the client capability
+   * {@link WorkspaceEditCapabilities#resourceOperations} document changes are either
+   * an array of {@link TextDocumentEdit}s to express changes to n different text
+   * documents where each text document edit addresses a specific version of
+   * a text document. Or it can contain above {@link TextDocumentEdit}s mixed with
+   * create, rename and delete file / folder operations.
+   * <p>
+   * Whether a client supports versioned document edits is expressed via
+   * {@link WorkspaceEditCapabilities#documentChanges} client capability.
+   * <p>
+   * If a client neither supports {@link WorkspaceEditCapabilities#documentChanges} nor
+   * {@link WorkspaceEditCapabilities#resourceOperations} then only plain {@link TextEdit}s
+   * using the {@link #changes} property are supported.
+   */
+  @JsonAdapter(DocumentChangeListAdapter.class)
+  private List<Either<TextDocumentEdit, ResourceOperation>> documentChanges;
+  
+  /**
+   * If resource changes are supported the `WorkspaceEdit`
+   * uses the property `resourceChanges` which are either a
+   * rename, move, delete or content change.
+   * <p>
+   * These changes are applied in the order that they are supplied,
+   * however clients may group the changes for optimization
+   * 
+   * @deprecated Since LSP introduces resource operations, use the {@link #documentChanges} instead
+   */
+  @Beta
+  @JsonAdapter(ResourceChangeListAdapter.class)
+  @Deprecated
+  private List<Either<ResourceChange, TextDocumentEdit>> resourceChanges;
+  
+  /**
+   * A map of change annotations that can be referenced in
+   * {@link AnnotatedTextEdit}s or {@link ResourceOperation}s.
+   * <p>
+   * Client support depends on {@link WorkspaceEditCapabilities#changeAnnotationSupport}.
+   * <p>
+   * Since 3.16.0
+   */
+  private Map<String, ChangeAnnotation> changeAnnotations;
+  
+  public WorkspaceEdit() {
+    LinkedHashMap<String, List<TextEdit>> _linkedHashMap = new LinkedHashMap<String, List<TextEdit>>();
+    this.changes = _linkedHashMap;
+  }
+  
+  public WorkspaceEdit(final Map<String, List<TextEdit>> changes) {
+    this.changes = changes;
+  }
+  
+  public WorkspaceEdit(final List<Either<TextDocumentEdit, ResourceOperation>> documentChanges) {
+    this.documentChanges = documentChanges;
+  }
+  
+  /**
+   * Holds changes to existing resources.
+   */
+  @Pure
+  public Map<String, List<TextEdit>> getChanges() {
+    return this.changes;
+  }
+  
+  /**
+   * Holds changes to existing resources.
+   */
+  public void setChanges(final Map<String, List<TextEdit>> changes) {
+    this.changes = changes;
+  }
+  
+  /**
+   * Depending on the client capability
+   * {@link WorkspaceEditCapabilities#resourceOperations} document changes are either
+   * an array of {@link TextDocumentEdit}s to express changes to n different text
+   * documents where each text document edit addresses a specific version of
+   * a text document. Or it can contain above {@link TextDocumentEdit}s mixed with
+   * create, rename and delete file / folder operations.
+   * <p>
+   * Whether a client supports versioned document edits is expressed via
+   * {@link WorkspaceEditCapabilities#documentChanges} client capability.
+   * <p>
+   * If a client neither supports {@link WorkspaceEditCapabilities#documentChanges} nor
+   * {@link WorkspaceEditCapabilities#resourceOperations} then only plain {@link TextEdit}s
+   * using the {@link #changes} property are supported.
+   */
+  @Pure
+  public List<Either<TextDocumentEdit, ResourceOperation>> getDocumentChanges() {
+    return this.documentChanges;
+  }
+  
+  /**
+   * Depending on the client capability
+   * {@link WorkspaceEditCapabilities#resourceOperations} document changes are either
+   * an array of {@link TextDocumentEdit}s to express changes to n different text
+   * documents where each text document edit addresses a specific version of
+   * a text document. Or it can contain above {@link TextDocumentEdit}s mixed with
+   * create, rename and delete file / folder operations.
+   * <p>
+   * Whether a client supports versioned document edits is expressed via
+   * {@link WorkspaceEditCapabilities#documentChanges} client capability.
+   * <p>
+   * If a client neither supports {@link WorkspaceEditCapabilities#documentChanges} nor
+   * {@link WorkspaceEditCapabilities#resourceOperations} then only plain {@link TextEdit}s
+   * using the {@link #changes} property are supported.
+   */
+  public void setDocumentChanges(final List<Either<TextDocumentEdit, ResourceOperation>> documentChanges) {
+    this.documentChanges = documentChanges;
+  }
+  
+  /**
+   * If resource changes are supported the `WorkspaceEdit`
+   * uses the property `resourceChanges` which are either a
+   * rename, move, delete or content change.
+   * <p>
+   * These changes are applied in the order that they are supplied,
+   * however clients may group the changes for optimization
+   * 
+   * @deprecated Since LSP introduces resource operations, use the {@link #documentChanges} instead
+   */
+  @Pure
+  @Deprecated
+  public List<Either<ResourceChange, TextDocumentEdit>> getResourceChanges() {
+    return this.resourceChanges;
+  }
+  
+  /**
+   * If resource changes are supported the `WorkspaceEdit`
+   * uses the property `resourceChanges` which are either a
+   * rename, move, delete or content change.
+   * <p>
+   * These changes are applied in the order that they are supplied,
+   * however clients may group the changes for optimization
+   * 
+   * @deprecated Since LSP introduces resource operations, use the {@link #documentChanges} instead
+   */
+  @Deprecated
+  public void setResourceChanges(final List<Either<ResourceChange, TextDocumentEdit>> resourceChanges) {
+    this.resourceChanges = resourceChanges;
+  }
+  
+  /**
+   * A map of change annotations that can be referenced in
+   * {@link AnnotatedTextEdit}s or {@link ResourceOperation}s.
+   * <p>
+   * Client support depends on {@link WorkspaceEditCapabilities#changeAnnotationSupport}.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public Map<String, ChangeAnnotation> getChangeAnnotations() {
+    return this.changeAnnotations;
+  }
+  
+  /**
+   * A map of change annotations that can be referenced in
+   * {@link AnnotatedTextEdit}s or {@link ResourceOperation}s.
+   * <p>
+   * Client support depends on {@link WorkspaceEditCapabilities#changeAnnotationSupport}.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setChangeAnnotations(final Map<String, ChangeAnnotation> changeAnnotations) {
+    this.changeAnnotations = changeAnnotations;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("changes", this.changes);
+    b.add("documentChanges", this.documentChanges);
+    b.add("resourceChanges", this.resourceChanges);
+    b.add("changeAnnotations", this.changeAnnotations);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    WorkspaceEdit other = (WorkspaceEdit) obj;
+    if (this.changes == null) {
+      if (other.changes != null)
+        return false;
+    } else if (!this.changes.equals(other.changes))
+      return false;
+    if (this.documentChanges == null) {
+      if (other.documentChanges != null)
+        return false;
+    } else if (!this.documentChanges.equals(other.documentChanges))
+      return false;
+    if (this.resourceChanges == null) {
+      if (other.resourceChanges != null)
+        return false;
+    } else if (!this.resourceChanges.equals(other.resourceChanges))
+      return false;
+    if (this.changeAnnotations == null) {
+      if (other.changeAnnotations != null)
+        return false;
+    } else if (!this.changeAnnotations.equals(other.changeAnnotations))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.changes== null) ? 0 : this.changes.hashCode());
+    result = prime * result + ((this.documentChanges== null) ? 0 : this.documentChanges.hashCode());
+    result = prime * result + ((this.resourceChanges== null) ? 0 : this.resourceChanges.hashCode());
+    return prime * result + ((this.changeAnnotations== null) ? 0 : this.changeAnnotations.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/WorkspaceEditCapabilities.java b/java/org/eclipse/lsp4j/WorkspaceEditCapabilities.java
new file mode 100644
index 0000000..935b1e2
--- /dev/null
+++ b/java/org/eclipse/lsp4j/WorkspaceEditCapabilities.java
@@ -0,0 +1,291 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import com.google.common.annotations.Beta;
+import java.util.List;
+import org.eclipse.lsp4j.WorkspaceEditChangeAnnotationSupportCapabilities;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Capabilities specific to {@link WorkspaceEdit}s
+ */
+@SuppressWarnings("all")
+public class WorkspaceEditCapabilities {
+  /**
+   * The client supports versioned document changes in {@link WorkspaceEdit}s
+   */
+  private Boolean documentChanges;
+  
+  /**
+   * The client supports resource changes
+   * in {@link WorkspaceEdit}s.
+   * 
+   * @deprecated Since LSP introduced resource operations, use {@link #resourceOperations}
+   */
+  @Deprecated
+  @Beta
+  private Boolean resourceChanges;
+  
+  /**
+   * The resource operations the client supports. Clients should at least
+   * support 'create', 'rename' and 'delete' files and folders.
+   * <p>
+   * See {@link ResourceOperationKind} for allowed values.
+   * <p>
+   * Since 3.13.0
+   */
+  private List<String> resourceOperations;
+  
+  /**
+   * The failure handling strategy of a client if applying the workspace edit
+   * fails.
+   * <p>
+   * See {@link FailureHandlingKind} for allowed values.
+   * <p>
+   * Since 3.13.0
+   */
+  private String failureHandling;
+  
+  /**
+   * Whether the client normalizes line endings to the client specific
+   * setting.
+   * <p>
+   * If set to {@code true} the client will normalize line ending characters
+   * in a workspace edit to the client specific new line character(s).
+   * <p>
+   * Since 3.16.0
+   */
+  private Boolean normalizesLineEndings;
+  
+  /**
+   * Whether the client in general supports change annotations on text edits,
+   * create file, rename file and delete file changes.
+   * <p>
+   * Since 3.16.0
+   */
+  private WorkspaceEditChangeAnnotationSupportCapabilities changeAnnotationSupport;
+  
+  public WorkspaceEditCapabilities() {
+  }
+  
+  @Deprecated
+  public WorkspaceEditCapabilities(final Boolean documentChanges) {
+    this.documentChanges = documentChanges;
+  }
+  
+  /**
+   * The client supports versioned document changes in {@link WorkspaceEdit}s
+   */
+  @Pure
+  public Boolean getDocumentChanges() {
+    return this.documentChanges;
+  }
+  
+  /**
+   * The client supports versioned document changes in {@link WorkspaceEdit}s
+   */
+  public void setDocumentChanges(final Boolean documentChanges) {
+    this.documentChanges = documentChanges;
+  }
+  
+  /**
+   * The client supports resource changes
+   * in {@link WorkspaceEdit}s.
+   * 
+   * @deprecated Since LSP introduced resource operations, use {@link #resourceOperations}
+   */
+  @Pure
+  @Deprecated
+  public Boolean getResourceChanges() {
+    return this.resourceChanges;
+  }
+  
+  /**
+   * The client supports resource changes
+   * in {@link WorkspaceEdit}s.
+   * 
+   * @deprecated Since LSP introduced resource operations, use {@link #resourceOperations}
+   */
+  @Deprecated
+  public void setResourceChanges(final Boolean resourceChanges) {
+    this.resourceChanges = resourceChanges;
+  }
+  
+  /**
+   * The resource operations the client supports. Clients should at least
+   * support 'create', 'rename' and 'delete' files and folders.
+   * <p>
+   * See {@link ResourceOperationKind} for allowed values.
+   * <p>
+   * Since 3.13.0
+   */
+  @Pure
+  public List<String> getResourceOperations() {
+    return this.resourceOperations;
+  }
+  
+  /**
+   * The resource operations the client supports. Clients should at least
+   * support 'create', 'rename' and 'delete' files and folders.
+   * <p>
+   * See {@link ResourceOperationKind} for allowed values.
+   * <p>
+   * Since 3.13.0
+   */
+  public void setResourceOperations(final List<String> resourceOperations) {
+    this.resourceOperations = resourceOperations;
+  }
+  
+  /**
+   * The failure handling strategy of a client if applying the workspace edit
+   * fails.
+   * <p>
+   * See {@link FailureHandlingKind} for allowed values.
+   * <p>
+   * Since 3.13.0
+   */
+  @Pure
+  public String getFailureHandling() {
+    return this.failureHandling;
+  }
+  
+  /**
+   * The failure handling strategy of a client if applying the workspace edit
+   * fails.
+   * <p>
+   * See {@link FailureHandlingKind} for allowed values.
+   * <p>
+   * Since 3.13.0
+   */
+  public void setFailureHandling(final String failureHandling) {
+    this.failureHandling = failureHandling;
+  }
+  
+  /**
+   * Whether the client normalizes line endings to the client specific
+   * setting.
+   * <p>
+   * If set to {@code true} the client will normalize line ending characters
+   * in a workspace edit to the client specific new line character(s).
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public Boolean getNormalizesLineEndings() {
+    return this.normalizesLineEndings;
+  }
+  
+  /**
+   * Whether the client normalizes line endings to the client specific
+   * setting.
+   * <p>
+   * If set to {@code true} the client will normalize line ending characters
+   * in a workspace edit to the client specific new line character(s).
+   * <p>
+   * Since 3.16.0
+   */
+  public void setNormalizesLineEndings(final Boolean normalizesLineEndings) {
+    this.normalizesLineEndings = normalizesLineEndings;
+  }
+  
+  /**
+   * Whether the client in general supports change annotations on text edits,
+   * create file, rename file and delete file changes.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public WorkspaceEditChangeAnnotationSupportCapabilities getChangeAnnotationSupport() {
+    return this.changeAnnotationSupport;
+  }
+  
+  /**
+   * Whether the client in general supports change annotations on text edits,
+   * create file, rename file and delete file changes.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setChangeAnnotationSupport(final WorkspaceEditChangeAnnotationSupportCapabilities changeAnnotationSupport) {
+    this.changeAnnotationSupport = changeAnnotationSupport;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("documentChanges", this.documentChanges);
+    b.add("resourceChanges", this.resourceChanges);
+    b.add("resourceOperations", this.resourceOperations);
+    b.add("failureHandling", this.failureHandling);
+    b.add("normalizesLineEndings", this.normalizesLineEndings);
+    b.add("changeAnnotationSupport", this.changeAnnotationSupport);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    WorkspaceEditCapabilities other = (WorkspaceEditCapabilities) obj;
+    if (this.documentChanges == null) {
+      if (other.documentChanges != null)
+        return false;
+    } else if (!this.documentChanges.equals(other.documentChanges))
+      return false;
+    if (this.resourceChanges == null) {
+      if (other.resourceChanges != null)
+        return false;
+    } else if (!this.resourceChanges.equals(other.resourceChanges))
+      return false;
+    if (this.resourceOperations == null) {
+      if (other.resourceOperations != null)
+        return false;
+    } else if (!this.resourceOperations.equals(other.resourceOperations))
+      return false;
+    if (this.failureHandling == null) {
+      if (other.failureHandling != null)
+        return false;
+    } else if (!this.failureHandling.equals(other.failureHandling))
+      return false;
+    if (this.normalizesLineEndings == null) {
+      if (other.normalizesLineEndings != null)
+        return false;
+    } else if (!this.normalizesLineEndings.equals(other.normalizesLineEndings))
+      return false;
+    if (this.changeAnnotationSupport == null) {
+      if (other.changeAnnotationSupport != null)
+        return false;
+    } else if (!this.changeAnnotationSupport.equals(other.changeAnnotationSupport))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.documentChanges== null) ? 0 : this.documentChanges.hashCode());
+    result = prime * result + ((this.resourceChanges== null) ? 0 : this.resourceChanges.hashCode());
+    result = prime * result + ((this.resourceOperations== null) ? 0 : this.resourceOperations.hashCode());
+    result = prime * result + ((this.failureHandling== null) ? 0 : this.failureHandling.hashCode());
+    result = prime * result + ((this.normalizesLineEndings== null) ? 0 : this.normalizesLineEndings.hashCode());
+    return prime * result + ((this.changeAnnotationSupport== null) ? 0 : this.changeAnnotationSupport.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/WorkspaceEditChangeAnnotationSupportCapabilities.java b/java/org/eclipse/lsp4j/WorkspaceEditChangeAnnotationSupportCapabilities.java
new file mode 100644
index 0000000..4e58fcd
--- /dev/null
+++ b/java/org/eclipse/lsp4j/WorkspaceEditChangeAnnotationSupportCapabilities.java
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Whether the client in general supports change annotations on text edits,
+ * create file, rename file and delete file changes.
+ * <p>
+ * Since 3.16.0
+ */
+@SuppressWarnings("all")
+public class WorkspaceEditChangeAnnotationSupportCapabilities {
+  /**
+   * Whether the client groups edits with equal labels into tree nodes,
+   * for instance all edits labelled with "Changes in Strings" would
+   * be a tree node.
+   */
+  private Boolean groupsOnLabel;
+  
+  public WorkspaceEditChangeAnnotationSupportCapabilities() {
+  }
+  
+  public WorkspaceEditChangeAnnotationSupportCapabilities(final Boolean groupsOnLabel) {
+    this.groupsOnLabel = groupsOnLabel;
+  }
+  
+  /**
+   * Whether the client groups edits with equal labels into tree nodes,
+   * for instance all edits labelled with "Changes in Strings" would
+   * be a tree node.
+   */
+  @Pure
+  public Boolean getGroupsOnLabel() {
+    return this.groupsOnLabel;
+  }
+  
+  /**
+   * Whether the client groups edits with equal labels into tree nodes,
+   * for instance all edits labelled with "Changes in Strings" would
+   * be a tree node.
+   */
+  public void setGroupsOnLabel(final Boolean groupsOnLabel) {
+    this.groupsOnLabel = groupsOnLabel;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("groupsOnLabel", this.groupsOnLabel);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    WorkspaceEditChangeAnnotationSupportCapabilities other = (WorkspaceEditChangeAnnotationSupportCapabilities) obj;
+    if (this.groupsOnLabel == null) {
+      if (other.groupsOnLabel != null)
+        return false;
+    } else if (!this.groupsOnLabel.equals(other.groupsOnLabel))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.groupsOnLabel== null) ? 0 : this.groupsOnLabel.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/WorkspaceFolder.java b/java/org/eclipse/lsp4j/WorkspaceFolder.java
new file mode 100644
index 0000000..032cb91
--- /dev/null
+++ b/java/org/eclipse/lsp4j/WorkspaceFolder.java
@@ -0,0 +1,121 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The workspace/workspaceFolders request is sent from the server to the client to fetch
+ * the current open list of workspace folders. Returns null in the response if only a single
+ * file is open in the tool. Returns an empty array if a workspace is open but no folders
+ * are configured.
+ */
+@SuppressWarnings("all")
+public class WorkspaceFolder {
+  /**
+   * The associated URI for this workspace folder.
+   */
+  @NonNull
+  private String uri;
+  
+  /**
+   * The name of the workspace folder. Defaults to the uri's basename.
+   */
+  private String name;
+  
+  public WorkspaceFolder() {
+  }
+  
+  public WorkspaceFolder(@NonNull final String uri) {
+    this.uri = Preconditions.<String>checkNotNull(uri, "uri");
+  }
+  
+  public WorkspaceFolder(@NonNull final String uri, final String name) {
+    this(uri);
+    this.name = name;
+  }
+  
+  /**
+   * The associated URI for this workspace folder.
+   */
+  @Pure
+  @NonNull
+  public String getUri() {
+    return this.uri;
+  }
+  
+  /**
+   * The associated URI for this workspace folder.
+   */
+  public void setUri(@NonNull final String uri) {
+    this.uri = Preconditions.checkNotNull(uri, "uri");
+  }
+  
+  /**
+   * The name of the workspace folder. Defaults to the uri's basename.
+   */
+  @Pure
+  public String getName() {
+    return this.name;
+  }
+  
+  /**
+   * The name of the workspace folder. Defaults to the uri's basename.
+   */
+  public void setName(final String name) {
+    this.name = name;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("uri", this.uri);
+    b.add("name", this.name);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    WorkspaceFolder other = (WorkspaceFolder) obj;
+    if (this.uri == null) {
+      if (other.uri != null)
+        return false;
+    } else if (!this.uri.equals(other.uri))
+      return false;
+    if (this.name == null) {
+      if (other.name != null)
+        return false;
+    } else if (!this.name.equals(other.name))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.uri== null) ? 0 : this.uri.hashCode());
+    return prime * result + ((this.name== null) ? 0 : this.name.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/WorkspaceFoldersChangeEvent.java b/java/org/eclipse/lsp4j/WorkspaceFoldersChangeEvent.java
new file mode 100644
index 0000000..e74b52a
--- /dev/null
+++ b/java/org/eclipse/lsp4j/WorkspaceFoldersChangeEvent.java
@@ -0,0 +1,121 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.lsp4j.WorkspaceFolder;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The workspace folder change event.
+ * <p>
+ * Since 3.6.0
+ */
+@SuppressWarnings("all")
+public class WorkspaceFoldersChangeEvent {
+  /**
+   * The array of added workspace folders
+   */
+  @NonNull
+  private List<WorkspaceFolder> added = new ArrayList<WorkspaceFolder>();
+  
+  /**
+   * The array of the removed workspace folders
+   */
+  @NonNull
+  private List<WorkspaceFolder> removed = new ArrayList<WorkspaceFolder>();
+  
+  public WorkspaceFoldersChangeEvent() {
+  }
+  
+  public WorkspaceFoldersChangeEvent(@NonNull final List<WorkspaceFolder> added, @NonNull final List<WorkspaceFolder> removed) {
+    this.added = Preconditions.<List<WorkspaceFolder>>checkNotNull(added, "added");
+    this.removed = Preconditions.<List<WorkspaceFolder>>checkNotNull(removed, "removed");
+  }
+  
+  /**
+   * The array of added workspace folders
+   */
+  @Pure
+  @NonNull
+  public List<WorkspaceFolder> getAdded() {
+    return this.added;
+  }
+  
+  /**
+   * The array of added workspace folders
+   */
+  public void setAdded(@NonNull final List<WorkspaceFolder> added) {
+    this.added = Preconditions.checkNotNull(added, "added");
+  }
+  
+  /**
+   * The array of the removed workspace folders
+   */
+  @Pure
+  @NonNull
+  public List<WorkspaceFolder> getRemoved() {
+    return this.removed;
+  }
+  
+  /**
+   * The array of the removed workspace folders
+   */
+  public void setRemoved(@NonNull final List<WorkspaceFolder> removed) {
+    this.removed = Preconditions.checkNotNull(removed, "removed");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("added", this.added);
+    b.add("removed", this.removed);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    WorkspaceFoldersChangeEvent other = (WorkspaceFoldersChangeEvent) obj;
+    if (this.added == null) {
+      if (other.added != null)
+        return false;
+    } else if (!this.added.equals(other.added))
+      return false;
+    if (this.removed == null) {
+      if (other.removed != null)
+        return false;
+    } else if (!this.removed.equals(other.removed))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.added== null) ? 0 : this.added.hashCode());
+    return prime * result + ((this.removed== null) ? 0 : this.removed.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/WorkspaceFoldersOptions.java b/java/org/eclipse/lsp4j/WorkspaceFoldersOptions.java
new file mode 100644
index 0000000..6adc38b
--- /dev/null
+++ b/java/org/eclipse/lsp4j/WorkspaceFoldersOptions.java
@@ -0,0 +1,139 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The server supports workspace folder.
+ * <p>
+ * Since 3.6.0
+ */
+@SuppressWarnings("all")
+public class WorkspaceFoldersOptions {
+  /**
+   * The server has support for workspace folders
+   */
+  private Boolean supported;
+  
+  /**
+   * Whether the server wants to receive workspace folder
+   * change notifications.
+   * <p>
+   * If a string is provided, the string is treated as an ID
+   * under which the notification is registered on the client
+   * side. The ID can be used to unregister for these events
+   * using the `client/unregisterCapability` request.
+   */
+  private Either<String, Boolean> changeNotifications;
+  
+  /**
+   * The server has support for workspace folders
+   */
+  @Pure
+  public Boolean getSupported() {
+    return this.supported;
+  }
+  
+  /**
+   * The server has support for workspace folders
+   */
+  public void setSupported(final Boolean supported) {
+    this.supported = supported;
+  }
+  
+  /**
+   * Whether the server wants to receive workspace folder
+   * change notifications.
+   * <p>
+   * If a string is provided, the string is treated as an ID
+   * under which the notification is registered on the client
+   * side. The ID can be used to unregister for these events
+   * using the `client/unregisterCapability` request.
+   */
+  @Pure
+  public Either<String, Boolean> getChangeNotifications() {
+    return this.changeNotifications;
+  }
+  
+  /**
+   * Whether the server wants to receive workspace folder
+   * change notifications.
+   * <p>
+   * If a string is provided, the string is treated as an ID
+   * under which the notification is registered on the client
+   * side. The ID can be used to unregister for these events
+   * using the `client/unregisterCapability` request.
+   */
+  public void setChangeNotifications(final Either<String, Boolean> changeNotifications) {
+    this.changeNotifications = changeNotifications;
+  }
+  
+  public void setChangeNotifications(final String changeNotifications) {
+    if (changeNotifications == null) {
+      this.changeNotifications = null;
+      return;
+    }
+    this.changeNotifications = Either.forLeft(changeNotifications);
+  }
+  
+  public void setChangeNotifications(final Boolean changeNotifications) {
+    if (changeNotifications == null) {
+      this.changeNotifications = null;
+      return;
+    }
+    this.changeNotifications = Either.forRight(changeNotifications);
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("supported", this.supported);
+    b.add("changeNotifications", this.changeNotifications);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    WorkspaceFoldersOptions other = (WorkspaceFoldersOptions) obj;
+    if (this.supported == null) {
+      if (other.supported != null)
+        return false;
+    } else if (!this.supported.equals(other.supported))
+      return false;
+    if (this.changeNotifications == null) {
+      if (other.changeNotifications != null)
+        return false;
+    } else if (!this.changeNotifications.equals(other.changeNotifications))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.supported== null) ? 0 : this.supported.hashCode());
+    return prime * result + ((this.changeNotifications== null) ? 0 : this.changeNotifications.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/WorkspaceServerCapabilities.java b/java/org/eclipse/lsp4j/WorkspaceServerCapabilities.java
new file mode 100644
index 0000000..4ea0974
--- /dev/null
+++ b/java/org/eclipse/lsp4j/WorkspaceServerCapabilities.java
@@ -0,0 +1,123 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.FileOperationsServerCapabilities;
+import org.eclipse.lsp4j.WorkspaceFoldersOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Workspace specific server capabilities
+ */
+@SuppressWarnings("all")
+public class WorkspaceServerCapabilities {
+  /**
+   * The server supports workspace folder.
+   * <p>
+   * Since 3.6.0
+   */
+  private WorkspaceFoldersOptions workspaceFolders;
+  
+  /**
+   * The server is interested in file notifications/requests.
+   * <p>
+   * Since 3.16.0
+   */
+  private FileOperationsServerCapabilities fileOperations;
+  
+  public WorkspaceServerCapabilities() {
+  }
+  
+  public WorkspaceServerCapabilities(final WorkspaceFoldersOptions workspaceFolders) {
+    this.workspaceFolders = workspaceFolders;
+  }
+  
+  /**
+   * The server supports workspace folder.
+   * <p>
+   * Since 3.6.0
+   */
+  @Pure
+  public WorkspaceFoldersOptions getWorkspaceFolders() {
+    return this.workspaceFolders;
+  }
+  
+  /**
+   * The server supports workspace folder.
+   * <p>
+   * Since 3.6.0
+   */
+  public void setWorkspaceFolders(final WorkspaceFoldersOptions workspaceFolders) {
+    this.workspaceFolders = workspaceFolders;
+  }
+  
+  /**
+   * The server is interested in file notifications/requests.
+   * <p>
+   * Since 3.16.0
+   */
+  @Pure
+  public FileOperationsServerCapabilities getFileOperations() {
+    return this.fileOperations;
+  }
+  
+  /**
+   * The server is interested in file notifications/requests.
+   * <p>
+   * Since 3.16.0
+   */
+  public void setFileOperations(final FileOperationsServerCapabilities fileOperations) {
+    this.fileOperations = fileOperations;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workspaceFolders", this.workspaceFolders);
+    b.add("fileOperations", this.fileOperations);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    WorkspaceServerCapabilities other = (WorkspaceServerCapabilities) obj;
+    if (this.workspaceFolders == null) {
+      if (other.workspaceFolders != null)
+        return false;
+    } else if (!this.workspaceFolders.equals(other.workspaceFolders))
+      return false;
+    if (this.fileOperations == null) {
+      if (other.fileOperations != null)
+        return false;
+    } else if (!this.fileOperations.equals(other.fileOperations))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.workspaceFolders== null) ? 0 : this.workspaceFolders.hashCode());
+    return prime * result + ((this.fileOperations== null) ? 0 : this.fileOperations.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/WorkspaceSymbolOptions.java b/java/org/eclipse/lsp4j/WorkspaceSymbolOptions.java
new file mode 100644
index 0000000..4b67f7c
--- /dev/null
+++ b/java/org/eclipse/lsp4j/WorkspaceSymbolOptions.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.AbstractWorkDoneProgressOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The options of a Workspace Symbol Request.
+ */
+@SuppressWarnings("all")
+public class WorkspaceSymbolOptions extends AbstractWorkDoneProgressOptions {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/WorkspaceSymbolParams.java b/java/org/eclipse/lsp4j/WorkspaceSymbolParams.java
new file mode 100644
index 0000000..71174f2
--- /dev/null
+++ b/java/org/eclipse/lsp4j/WorkspaceSymbolParams.java
@@ -0,0 +1,92 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.WorkDoneProgressAndPartialResultParams;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.util.Preconditions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The parameters of a Workspace Symbol Request.
+ */
+@SuppressWarnings("all")
+public class WorkspaceSymbolParams extends WorkDoneProgressAndPartialResultParams {
+  /**
+   * A query string to filter symbols by. Clients may send an empty
+   * string here to request all symbols.
+   */
+  @NonNull
+  private String query;
+  
+  public WorkspaceSymbolParams() {
+  }
+  
+  public WorkspaceSymbolParams(@NonNull final String query) {
+    this.query = Preconditions.<String>checkNotNull(query, "query");
+  }
+  
+  /**
+   * A query string to filter symbols by. Clients may send an empty
+   * string here to request all symbols.
+   */
+  @Pure
+  @NonNull
+  public String getQuery() {
+    return this.query;
+  }
+  
+  /**
+   * A query string to filter symbols by. Clients may send an empty
+   * string here to request all symbols.
+   */
+  public void setQuery(@NonNull final String query) {
+    this.query = Preconditions.checkNotNull(query, "query");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("query", this.query);
+    b.add("workDoneToken", getWorkDoneToken());
+    b.add("partialResultToken", getPartialResultToken());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    WorkspaceSymbolParams other = (WorkspaceSymbolParams) obj;
+    if (this.query == null) {
+      if (other.query != null)
+        return false;
+    } else if (!this.query.equals(other.query))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * super.hashCode() + ((this.query== null) ? 0 : this.query.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/WorkspaceSymbolRegistrationOptions.java b/java/org/eclipse/lsp4j/WorkspaceSymbolRegistrationOptions.java
new file mode 100644
index 0000000..3c0a570
--- /dev/null
+++ b/java/org/eclipse/lsp4j/WorkspaceSymbolRegistrationOptions.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j;
+
+import org.eclipse.lsp4j.WorkspaceSymbolOptions;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The options of a Workspace Symbol Registration Request.
+ */
+@SuppressWarnings("all")
+public class WorkspaceSymbolRegistrationOptions extends WorkspaceSymbolOptions {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("workDoneProgress", getWorkDoneProgress());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return super.hashCode();
+  }
+}
diff --git a/java/org/eclipse/lsp4j/adapters/CodeActionResponseAdapter.java b/java/org/eclipse/lsp4j/adapters/CodeActionResponseAdapter.java
new file mode 100644
index 0000000..aec2452
--- /dev/null
+++ b/java/org/eclipse/lsp4j/adapters/CodeActionResponseAdapter.java
@@ -0,0 +1,46 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.adapters;
+
+import java.util.ArrayList;
+import java.util.function.Predicate;
+
+import org.eclipse.lsp4j.CodeAction;
+import org.eclipse.lsp4j.Command;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.CollectionTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.EitherTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.EitherTypeAdapter.PropertyChecker;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+
+public class CodeActionResponseAdapter implements TypeAdapterFactory {
+	
+	private static final TypeToken<Either<Command, CodeAction>> ELEMENT_TYPE
+			= new TypeToken<Either<Command, CodeAction>>() {};
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
+		Predicate<JsonElement> leftChecker = new PropertyChecker("command", JsonPrimitive.class);
+		Predicate<JsonElement> rightChecker = new PropertyChecker("title");
+		TypeAdapter<Either<Command, CodeAction>> elementTypeAdapter = new EitherTypeAdapter<>(gson,
+				ELEMENT_TYPE, leftChecker, rightChecker);
+		return (TypeAdapter<T>) new CollectionTypeAdapter<>(gson, ELEMENT_TYPE.getType(), elementTypeAdapter, ArrayList::new);
+	}
+	
+}
diff --git a/java/org/eclipse/lsp4j/adapters/CompletionItemTextEditTypeAdapter.java b/java/org/eclipse/lsp4j/adapters/CompletionItemTextEditTypeAdapter.java
new file mode 100644
index 0000000..68cc1c5
--- /dev/null
+++ b/java/org/eclipse/lsp4j/adapters/CompletionItemTextEditTypeAdapter.java
@@ -0,0 +1,37 @@
+/******************************************************************************
+ * Copyright (c) 2020 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+
+package org.eclipse.lsp4j.adapters;
+
+import org.eclipse.lsp4j.InsertReplaceEdit;
+import org.eclipse.lsp4j.TextEdit;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.EitherTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.EitherTypeAdapter.PropertyChecker;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+
+import com.google.gson.Gson;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+
+public class CompletionItemTextEditTypeAdapter implements TypeAdapterFactory {
+	private static final TypeToken<Either<TextEdit, InsertReplaceEdit>> ELEMENT_TYPE
+			= new TypeToken<Either<TextEdit, InsertReplaceEdit>>() {};
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
+		PropertyChecker leftChecker = new PropertyChecker("range");
+		PropertyChecker rightChecker = new PropertyChecker("insert");
+		return (TypeAdapter<T>) new EitherTypeAdapter<>(gson, ELEMENT_TYPE, leftChecker, rightChecker);
+	}
+}
diff --git a/java/org/eclipse/lsp4j/adapters/DocumentChangeListAdapter.java b/java/org/eclipse/lsp4j/adapters/DocumentChangeListAdapter.java
new file mode 100644
index 0000000..68d9474
--- /dev/null
+++ b/java/org/eclipse/lsp4j/adapters/DocumentChangeListAdapter.java
@@ -0,0 +1,45 @@
+/******************************************************************************
+ * Copyright (c) 2018 Microsoft Corporation and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+
+package org.eclipse.lsp4j.adapters;
+
+import java.util.ArrayList;
+import java.util.function.Predicate;
+
+import org.eclipse.lsp4j.ResourceOperation;
+import org.eclipse.lsp4j.TextDocumentEdit;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.CollectionTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.EitherTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.EitherTypeAdapter.PropertyChecker;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+
+public class DocumentChangeListAdapter implements TypeAdapterFactory {
+	
+	private static final TypeToken<Either<TextDocumentEdit, ResourceOperation>> ELEMENT_TYPE
+			= new TypeToken<Either<TextDocumentEdit, ResourceOperation>>() {};
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
+		Predicate<JsonElement> leftChecker = new PropertyChecker("textDocument").and(new PropertyChecker("edits"));
+		Predicate<JsonElement> rightChecker = new PropertyChecker("kind");
+		TypeAdapter<Either<TextDocumentEdit, ResourceOperation>> elementTypeAdapter = new EitherTypeAdapter<>(gson,
+				ELEMENT_TYPE, leftChecker, rightChecker);
+		return (TypeAdapter<T>) new CollectionTypeAdapter<>(gson, ELEMENT_TYPE.getType(), elementTypeAdapter, ArrayList::new);
+	}
+}
diff --git a/java/org/eclipse/lsp4j/adapters/DocumentSymbolResponseAdapter.java b/java/org/eclipse/lsp4j/adapters/DocumentSymbolResponseAdapter.java
new file mode 100644
index 0000000..0a4d7ba
--- /dev/null
+++ b/java/org/eclipse/lsp4j/adapters/DocumentSymbolResponseAdapter.java
@@ -0,0 +1,43 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.adapters;
+
+import java.util.ArrayList;
+
+import org.eclipse.lsp4j.DocumentSymbol;
+import org.eclipse.lsp4j.SymbolInformation;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.CollectionTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.EitherTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.EitherTypeAdapter.PropertyChecker;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+
+import com.google.gson.Gson;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+
+public class DocumentSymbolResponseAdapter implements TypeAdapterFactory {
+	
+	private static final TypeToken<Either<SymbolInformation, DocumentSymbol>> ELEMENT_TYPE
+			= new TypeToken<Either<SymbolInformation, DocumentSymbol>>() {};
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
+		PropertyChecker leftChecker = new PropertyChecker("location");
+		PropertyChecker rightChecker = new PropertyChecker("range");
+		TypeAdapter<Either<SymbolInformation, DocumentSymbol>> elementTypeAdapter = new EitherTypeAdapter<>(gson,
+				ELEMENT_TYPE, leftChecker, rightChecker);
+		return (TypeAdapter<T>) new CollectionTypeAdapter<>(gson, ELEMENT_TYPE.getType(), elementTypeAdapter, ArrayList::new);
+	}
+	
+}
diff --git a/java/org/eclipse/lsp4j/adapters/HoverTypeAdapter.java b/java/org/eclipse/lsp4j/adapters/HoverTypeAdapter.java
new file mode 100644
index 0000000..8665f20
--- /dev/null
+++ b/java/org/eclipse/lsp4j/adapters/HoverTypeAdapter.java
@@ -0,0 +1,151 @@
+/**
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.adapters;
+
+import com.google.common.base.Objects;
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
+import java.util.List;
+import org.eclipse.lsp4j.Hover;
+import org.eclipse.lsp4j.MarkedString;
+import org.eclipse.lsp4j.MarkupContent;
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.generator.TypeAdapterImpl;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.xtext.xbase.lib.CollectionLiterals;
+
+/**
+ * A type adapter for the Hover protocol type.
+ */
+@TypeAdapterImpl(Hover.class)
+@SuppressWarnings("all")
+public class HoverTypeAdapter extends TypeAdapter<Hover> {
+  public static class Factory implements TypeAdapterFactory {
+    public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> typeToken) {
+      if (!Hover.class.isAssignableFrom(typeToken.getRawType())) {
+      	return null;
+      }
+      return (TypeAdapter<T>) new HoverTypeAdapter(gson);
+    }
+  }
+  
+  private static final TypeToken<List<Either<String, MarkedString>>> LIST_STRING_MARKEDSTRING = new TypeToken<List<Either<String, MarkedString>>>() {
+  };
+  
+  private static final TypeToken<Either<String, MarkedString>> STRING_MARKEDSTRING = new TypeToken<Either<String, MarkedString>>() {
+  };
+  
+  protected Either<List<Either<String, MarkedString>>, MarkupContent> readContents(final JsonReader in) throws IOException {
+    final JsonToken nextToken = in.peek();
+    boolean _equals = Objects.equal(nextToken, JsonToken.STRING);
+    if (_equals) {
+      final List<Either<String, MarkedString>> value = CollectionLiterals.<Either<String, MarkedString>>newArrayList(Either.<String, MarkedString>forLeft(in.nextString()));
+      return Either.<List<Either<String, MarkedString>>, MarkupContent>forLeft(value);
+    } else {
+      boolean _equals_1 = Objects.equal(nextToken, JsonToken.BEGIN_ARRAY);
+      if (_equals_1) {
+        final List<Either<String, MarkedString>> value_1 = this.gson.<List<Either<String, MarkedString>>>fromJson(in, HoverTypeAdapter.LIST_STRING_MARKEDSTRING.getType());
+        return Either.<List<Either<String, MarkedString>>, MarkupContent>forLeft(value_1);
+      } else {
+        JsonElement _parseReader = JsonParser.parseReader(in);
+        final JsonObject object = ((JsonObject) _parseReader);
+        boolean _has = object.has("language");
+        if (_has) {
+          final List<Either<String, MarkedString>> value_2 = CollectionLiterals.<Either<String, MarkedString>>newArrayList(Either.<String, MarkedString>forRight(this.gson.<MarkedString>fromJson(object, MarkedString.class)));
+          return Either.<List<Either<String, MarkedString>>, MarkupContent>forLeft(value_2);
+        } else {
+          return Either.<List<Either<String, MarkedString>>, MarkupContent>forRight(this.gson.<MarkupContent>fromJson(object, MarkupContent.class));
+        }
+      }
+    }
+  }
+  
+  protected void writeContents(final JsonWriter out, final Either<List<Either<String, MarkedString>>, MarkupContent> contents) throws IOException {
+    boolean _isLeft = contents.isLeft();
+    if (_isLeft) {
+      final List<Either<String, MarkedString>> list = contents.getLeft();
+      int _size = list.size();
+      boolean _equals = (_size == 1);
+      if (_equals) {
+        this.gson.toJson(list.get(0), HoverTypeAdapter.STRING_MARKEDSTRING.getType(), out);
+      } else {
+        this.gson.toJson(list, HoverTypeAdapter.LIST_STRING_MARKEDSTRING.getType(), out);
+      }
+    } else {
+      this.gson.toJson(contents.getRight(), MarkupContent.class, out);
+    }
+  }
+  
+  private static final TypeToken<Either<List<Either<String, MarkedString>>, MarkupContent>> CONTENTS_TYPE_TOKEN = new TypeToken<Either<List<Either<String, MarkedString>>, MarkupContent>>() {};
+  
+  private final Gson gson;
+  
+  public HoverTypeAdapter(final Gson gson) {
+    this.gson = gson;
+  }
+  
+  public Hover read(final JsonReader in) throws IOException {
+    JsonToken nextToken = in.peek();
+    if (nextToken == JsonToken.NULL) {
+    	return null;
+    }
+    
+    Hover result = new Hover();
+    in.beginObject();
+    while (in.hasNext()) {
+    	String name = in.nextName();
+    	switch (name) {
+    	case "contents":
+    		result.setContents(readContents(in));
+    		break;
+    	case "range":
+    		result.setRange(readRange(in));
+    		break;
+    	default:
+    		in.skipValue();
+    	}
+    }
+    in.endObject();
+    return result;
+  }
+  
+  protected Range readRange(final JsonReader in) throws IOException {
+    return gson.fromJson(in, Range.class);
+  }
+  
+  public void write(final JsonWriter out, final Hover value) throws IOException {
+    if (value == null) {
+    	out.nullValue();
+    	return;
+    }
+    
+    out.beginObject();
+    out.name("contents");
+    writeContents(out, value.getContents());
+    out.name("range");
+    writeRange(out, value.getRange());
+    out.endObject();
+  }
+  
+  protected void writeRange(final JsonWriter out, final Range value) throws IOException {
+    gson.toJson(value, Range.class, out);
+  }
+}
diff --git a/java/org/eclipse/lsp4j/adapters/HoverTypeAdapter.xtend b/java/org/eclipse/lsp4j/adapters/HoverTypeAdapter.xtend
new file mode 100644
index 0000000..94ddde3
--- /dev/null
+++ b/java/org/eclipse/lsp4j/adapters/HoverTypeAdapter.xtend
@@ -0,0 +1,69 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.adapters
+
+import com.google.gson.JsonObject
+import com.google.gson.JsonParser
+import com.google.gson.reflect.TypeToken
+import com.google.gson.stream.JsonReader
+import com.google.gson.stream.JsonToken
+import com.google.gson.stream.JsonWriter
+import java.io.IOException
+import java.util.List
+import org.eclipse.lsp4j.Hover
+import org.eclipse.lsp4j.MarkedString
+import org.eclipse.lsp4j.MarkupContent
+import org.eclipse.lsp4j.generator.TypeAdapterImpl
+import org.eclipse.lsp4j.jsonrpc.messages.Either
+
+/**
+ * A type adapter for the Hover protocol type.
+ */
+@TypeAdapterImpl(Hover)
+class HoverTypeAdapter {
+	
+	static val LIST_STRING_MARKEDSTRING = new TypeToken<List<Either<String, MarkedString>>>() {}
+	static val STRING_MARKEDSTRING = new TypeToken<Either<String, MarkedString>>() {}
+	
+	protected def readContents(JsonReader in) throws IOException {
+		val nextToken = in.peek()
+		if (nextToken == JsonToken.STRING) {
+			val List<Either<String, MarkedString>> value = newArrayList(Either.forLeft(in.nextString))
+			return Either.forLeft(value)
+		} else if (nextToken == JsonToken.BEGIN_ARRAY) {
+			val value = gson.fromJson(in, LIST_STRING_MARKEDSTRING.type)
+			return Either.forLeft(value)
+		} else {
+			val object = JsonParser.parseReader(in) as JsonObject
+			if (object.has("language")) {
+				val List<Either<String, MarkedString>> value = newArrayList(Either.forRight(gson.fromJson(object, MarkedString)))
+				return Either.forLeft(value)
+			} else {
+				return Either.forRight(gson.fromJson(object, MarkupContent))
+			}
+		}
+	}
+	
+	protected def writeContents(JsonWriter out, Either<List<Either<String, MarkedString>>, MarkupContent> contents) throws IOException {
+		if (contents.isLeft) {
+			val list = contents.getLeft
+			if (list.size == 1) {
+				gson.toJson(list.get(0), STRING_MARKEDSTRING.type, out)
+			} else {
+				gson.toJson(list, LIST_STRING_MARKEDSTRING.type, out)
+			}
+		} else {
+			gson.toJson(contents.getRight, MarkupContent, out)
+		}
+	}
+	
+}
\ No newline at end of file
diff --git a/java/org/eclipse/lsp4j/adapters/InitializeParamsTypeAdapter.java b/java/org/eclipse/lsp4j/adapters/InitializeParamsTypeAdapter.java
new file mode 100644
index 0000000..68e10bc
--- /dev/null
+++ b/java/org/eclipse/lsp4j/adapters/InitializeParamsTypeAdapter.java
@@ -0,0 +1,244 @@
+/**
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.adapters;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
+import java.util.List;
+import org.eclipse.lsp4j.ClientCapabilities;
+import org.eclipse.lsp4j.ClientInfo;
+import org.eclipse.lsp4j.InitializeParams;
+import org.eclipse.lsp4j.WorkspaceFolder;
+import org.eclipse.lsp4j.generator.TypeAdapterImpl;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+
+/**
+ * A type adapter for the InitializeParams protocol type.
+ */
+@TypeAdapterImpl(InitializeParams.class)
+@SuppressWarnings("all")
+public class InitializeParamsTypeAdapter extends TypeAdapter<InitializeParams> {
+  public static class Factory implements TypeAdapterFactory {
+    public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> typeToken) {
+      if (!InitializeParams.class.isAssignableFrom(typeToken.getRawType())) {
+      	return null;
+      }
+      return (TypeAdapter<T>) new InitializeParamsTypeAdapter(gson);
+    }
+  }
+  
+  protected Object readInitializationOptions(final JsonReader in) throws IOException {
+    return this.gson.<JsonElement>getAdapter(JsonElement.class).read(in);
+  }
+  
+  protected void writeProcessId(final JsonWriter out, final Integer value) throws IOException {
+    if ((value == null)) {
+      final boolean previousSerializeNulls = out.getSerializeNulls();
+      out.setSerializeNulls(true);
+      out.nullValue();
+      out.setSerializeNulls(previousSerializeNulls);
+    } else {
+      out.value(value);
+    }
+  }
+  
+  protected void writeRootUri(final JsonWriter out, final String value) throws IOException {
+    if ((value == null)) {
+      final boolean previousSerializeNulls = out.getSerializeNulls();
+      out.setSerializeNulls(true);
+      out.nullValue();
+      out.setSerializeNulls(previousSerializeNulls);
+    } else {
+      out.value(value);
+    }
+  }
+  
+  private static final TypeToken<Either<String, Integer>> WORKDONETOKEN_TYPE_TOKEN = new TypeToken<Either<String, Integer>>() {};
+  
+  private static final TypeToken<List<WorkspaceFolder>> WORKSPACEFOLDERS_TYPE_TOKEN = new TypeToken<List<WorkspaceFolder>>() {};
+  
+  private final Gson gson;
+  
+  public InitializeParamsTypeAdapter(final Gson gson) {
+    this.gson = gson;
+  }
+  
+  public InitializeParams read(final JsonReader in) throws IOException {
+    JsonToken nextToken = in.peek();
+    if (nextToken == JsonToken.NULL) {
+    	return null;
+    }
+    
+    InitializeParams result = new InitializeParams();
+    in.beginObject();
+    while (in.hasNext()) {
+    	String name = in.nextName();
+    	switch (name) {
+    	case "workDoneToken":
+    		result.setWorkDoneToken(readWorkDoneToken(in));
+    		break;
+    	case "processId":
+    		result.setProcessId(readProcessId(in));
+    		break;
+    	case "rootPath":
+    		result.setRootPath(readRootPath(in));
+    		break;
+    	case "rootUri":
+    		result.setRootUri(readRootUri(in));
+    		break;
+    	case "initializationOptions":
+    		result.setInitializationOptions(readInitializationOptions(in));
+    		break;
+    	case "capabilities":
+    		result.setCapabilities(readCapabilities(in));
+    		break;
+    	case "clientName":
+    		result.setClientName(readClientName(in));
+    		break;
+    	case "clientInfo":
+    		result.setClientInfo(readClientInfo(in));
+    		break;
+    	case "locale":
+    		result.setLocale(readLocale(in));
+    		break;
+    	case "trace":
+    		result.setTrace(readTrace(in));
+    		break;
+    	case "workspaceFolders":
+    		result.setWorkspaceFolders(readWorkspaceFolders(in));
+    		break;
+    	default:
+    		in.skipValue();
+    	}
+    }
+    in.endObject();
+    return result;
+  }
+  
+  protected Either<String, Integer> readWorkDoneToken(final JsonReader in) throws IOException {
+    return gson.fromJson(in, WORKDONETOKEN_TYPE_TOKEN.getType());
+  }
+  
+  protected Integer readProcessId(final JsonReader in) throws IOException {
+    return gson.fromJson(in, Integer.class);
+  }
+  
+  protected String readRootPath(final JsonReader in) throws IOException {
+    return gson.fromJson(in, String.class);
+  }
+  
+  protected String readRootUri(final JsonReader in) throws IOException {
+    return gson.fromJson(in, String.class);
+  }
+  
+  protected ClientCapabilities readCapabilities(final JsonReader in) throws IOException {
+    return gson.fromJson(in, ClientCapabilities.class);
+  }
+  
+  protected String readClientName(final JsonReader in) throws IOException {
+    return gson.fromJson(in, String.class);
+  }
+  
+  protected ClientInfo readClientInfo(final JsonReader in) throws IOException {
+    return gson.fromJson(in, ClientInfo.class);
+  }
+  
+  protected String readLocale(final JsonReader in) throws IOException {
+    return gson.fromJson(in, String.class);
+  }
+  
+  protected String readTrace(final JsonReader in) throws IOException {
+    return gson.fromJson(in, String.class);
+  }
+  
+  protected List<WorkspaceFolder> readWorkspaceFolders(final JsonReader in) throws IOException {
+    return gson.fromJson(in, WORKSPACEFOLDERS_TYPE_TOKEN.getType());
+  }
+  
+  public void write(final JsonWriter out, final InitializeParams value) throws IOException {
+    if (value == null) {
+    	out.nullValue();
+    	return;
+    }
+    
+    out.beginObject();
+    out.name("workDoneToken");
+    writeWorkDoneToken(out, value.getWorkDoneToken());
+    out.name("processId");
+    writeProcessId(out, value.getProcessId());
+    out.name("rootPath");
+    writeRootPath(out, value.getRootPath());
+    out.name("rootUri");
+    writeRootUri(out, value.getRootUri());
+    out.name("initializationOptions");
+    writeInitializationOptions(out, value.getInitializationOptions());
+    out.name("capabilities");
+    writeCapabilities(out, value.getCapabilities());
+    out.name("clientName");
+    writeClientName(out, value.getClientName());
+    out.name("clientInfo");
+    writeClientInfo(out, value.getClientInfo());
+    out.name("locale");
+    writeLocale(out, value.getLocale());
+    out.name("trace");
+    writeTrace(out, value.getTrace());
+    out.name("workspaceFolders");
+    writeWorkspaceFolders(out, value.getWorkspaceFolders());
+    out.endObject();
+  }
+  
+  protected void writeWorkDoneToken(final JsonWriter out, final Either<String, Integer> value) throws IOException {
+    gson.toJson(value, WORKDONETOKEN_TYPE_TOKEN.getType(), out);
+  }
+  
+  protected void writeRootPath(final JsonWriter out, final String value) throws IOException {
+    out.value(value);
+  }
+  
+  protected void writeInitializationOptions(final JsonWriter out, final Object value) throws IOException {
+    if (value == null)
+    	out.nullValue();
+    else
+    	gson.toJson(value, value.getClass(), out);
+  }
+  
+  protected void writeCapabilities(final JsonWriter out, final ClientCapabilities value) throws IOException {
+    gson.toJson(value, ClientCapabilities.class, out);
+  }
+  
+  protected void writeClientName(final JsonWriter out, final String value) throws IOException {
+    out.value(value);
+  }
+  
+  protected void writeClientInfo(final JsonWriter out, final ClientInfo value) throws IOException {
+    gson.toJson(value, ClientInfo.class, out);
+  }
+  
+  protected void writeLocale(final JsonWriter out, final String value) throws IOException {
+    out.value(value);
+  }
+  
+  protected void writeTrace(final JsonWriter out, final String value) throws IOException {
+    out.value(value);
+  }
+  
+  protected void writeWorkspaceFolders(final JsonWriter out, final List<WorkspaceFolder> value) throws IOException {
+    gson.toJson(value, WORKSPACEFOLDERS_TYPE_TOKEN.getType(), out);
+  }
+}
diff --git a/java/org/eclipse/lsp4j/adapters/InitializeParamsTypeAdapter.xtend b/java/org/eclipse/lsp4j/adapters/InitializeParamsTypeAdapter.xtend
new file mode 100644
index 0000000..6e20c92
--- /dev/null
+++ b/java/org/eclipse/lsp4j/adapters/InitializeParamsTypeAdapter.xtend
@@ -0,0 +1,53 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.adapters
+
+import com.google.gson.JsonElement;
+import com.google.gson.stream.JsonReader
+import com.google.gson.stream.JsonWriter
+import java.io.IOException
+import org.eclipse.lsp4j.InitializeParams
+import org.eclipse.lsp4j.generator.TypeAdapterImpl
+
+/**
+ * A type adapter for the InitializeParams protocol type.
+ */
+@TypeAdapterImpl(InitializeParams)
+class InitializeParamsTypeAdapter {
+
+	protected def Object readInitializationOptions(JsonReader in) throws IOException {
+		return gson.getAdapter(JsonElement).read(in);
+	}
+
+	protected def void writeProcessId(JsonWriter out, Integer value) throws IOException {
+		if (value === null) {
+			val previousSerializeNulls = out.serializeNulls
+			out.serializeNulls = true
+			out.nullValue()
+			out.serializeNulls = previousSerializeNulls
+		} else {
+			out.value(value)
+		}
+	}
+
+	protected def void writeRootUri(JsonWriter out, String value) throws IOException {
+		if (value === null) {
+			val previousSerializeNulls = out.serializeNulls
+			out.serializeNulls = true
+			out.nullValue()
+			out.serializeNulls = previousSerializeNulls
+		} else {
+			out.value(value)
+		}
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/adapters/LocationLinkListAdapter.java b/java/org/eclipse/lsp4j/adapters/LocationLinkListAdapter.java
new file mode 100644
index 0000000..50ac650
--- /dev/null
+++ b/java/org/eclipse/lsp4j/adapters/LocationLinkListAdapter.java
@@ -0,0 +1,30 @@
+package org.eclipse.lsp4j.adapters;
+
+import java.util.List;
+
+import org.eclipse.lsp4j.Location;
+import org.eclipse.lsp4j.LocationLink;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.EitherTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.EitherTypeAdapter.ListChecker;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.EitherTypeAdapter.PropertyChecker;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+
+import com.google.gson.Gson;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+
+public class LocationLinkListAdapter implements TypeAdapterFactory {
+	
+	private static final TypeToken<Either<List<? extends Location>, List<? extends LocationLink>>> EITHER_TYPE
+			= new TypeToken<Either<List<? extends Location>, List<? extends LocationLink>>>() {};
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
+		ListChecker leftChecker = new ListChecker(new PropertyChecker("uri"), true);
+		ListChecker rightChecker = new ListChecker(new PropertyChecker("targetUri"), false);
+		return (TypeAdapter<T>) new EitherTypeAdapter<>(gson, EITHER_TYPE, leftChecker, rightChecker);
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/adapters/PrepareRenameResponseAdapter.java b/java/org/eclipse/lsp4j/adapters/PrepareRenameResponseAdapter.java
new file mode 100644
index 0000000..e626592
--- /dev/null
+++ b/java/org/eclipse/lsp4j/adapters/PrepareRenameResponseAdapter.java
@@ -0,0 +1,40 @@
+/******************************************************************************
+ * Copyright (c) 2018-2019 Microsoft Corporation and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.adapters;
+
+import java.util.function.Predicate;
+
+import org.eclipse.lsp4j.PrepareRenameResult;
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.EitherTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.EitherTypeAdapter.PropertyChecker;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+
+public class PrepareRenameResponseAdapter implements TypeAdapterFactory {
+	
+	private static final TypeToken<Either<Range, PrepareRenameResult>> ELEMENT_TYPE
+			= new TypeToken<Either<Range, PrepareRenameResult>>() {};
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
+		Predicate<JsonElement> leftChecker = new PropertyChecker("start");
+		Predicate<JsonElement> rightChecker = new PropertyChecker("range");
+		return (TypeAdapter<T>) new EitherTypeAdapter<>(gson, ELEMENT_TYPE, leftChecker, rightChecker);
+	}
+}
diff --git a/java/org/eclipse/lsp4j/adapters/ProgressNotificationAdapter.java b/java/org/eclipse/lsp4j/adapters/ProgressNotificationAdapter.java
new file mode 100644
index 0000000..64a4f6f
--- /dev/null
+++ b/java/org/eclipse/lsp4j/adapters/ProgressNotificationAdapter.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2021 1C-Soft LLC and others.
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ *******************************************************************************/
+package org.eclipse.lsp4j.adapters;
+
+import java.util.function.Predicate;
+
+import org.eclipse.lsp4j.WorkDoneProgressNotification;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.EitherTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.EitherTypeAdapter.PropertyChecker;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+
+public class ProgressNotificationAdapter implements TypeAdapterFactory {
+
+	private static final TypeToken<Either<WorkDoneProgressNotification, Object>> ELEMENT_TYPE
+			= new TypeToken<Either<WorkDoneProgressNotification, Object>>() {};
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
+		Gson gson2 = gson.newBuilder().registerTypeHierarchyAdapter(WorkDoneProgressNotification.class,
+				new WorkDoneProgressNotificationAdapter()).create();
+		Predicate<JsonElement> leftChecker = new PropertyChecker("kind", "begin").or(
+				new PropertyChecker("kind", "report")).or(new PropertyChecker("kind", "end"));
+		Predicate<JsonElement> rightChecker = t -> true;
+		return (TypeAdapter<T>) new EitherTypeAdapter<>(gson2, ELEMENT_TYPE, leftChecker, rightChecker);
+	}
+}
diff --git a/java/org/eclipse/lsp4j/adapters/ResourceChangeListAdapter.java b/java/org/eclipse/lsp4j/adapters/ResourceChangeListAdapter.java
new file mode 100644
index 0000000..7c61961
--- /dev/null
+++ b/java/org/eclipse/lsp4j/adapters/ResourceChangeListAdapter.java
@@ -0,0 +1,46 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.adapters;
+
+import java.util.ArrayList;
+import java.util.function.Predicate;
+
+import org.eclipse.lsp4j.ResourceChange;
+import org.eclipse.lsp4j.TextDocumentEdit;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.CollectionTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.EitherTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.EitherTypeAdapter.PropertyChecker;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+
+@SuppressWarnings("deprecation")
+public class ResourceChangeListAdapter implements TypeAdapterFactory {
+	
+	private static final TypeToken<Either<ResourceChange, TextDocumentEdit>> ELEMENT_TYPE
+			= new TypeToken<Either<ResourceChange, TextDocumentEdit>>() {};
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
+		Predicate<JsonElement> leftChecker = new PropertyChecker("current").or(new PropertyChecker("newUri"));
+		Predicate<JsonElement> rightChecker = new PropertyChecker("textDocument").and(new PropertyChecker("edits"));
+		TypeAdapter<Either<ResourceChange, TextDocumentEdit>> elementTypeAdapter = new EitherTypeAdapter<>(gson,
+				ELEMENT_TYPE, leftChecker, rightChecker);
+		return (TypeAdapter<T>) new CollectionTypeAdapter<>(gson, ELEMENT_TYPE.getType(), elementTypeAdapter, ArrayList::new);
+	}
+	
+}
\ No newline at end of file
diff --git a/java/org/eclipse/lsp4j/adapters/ResourceOperationTypeAdapter.java b/java/org/eclipse/lsp4j/adapters/ResourceOperationTypeAdapter.java
new file mode 100644
index 0000000..2c661ee
--- /dev/null
+++ b/java/org/eclipse/lsp4j/adapters/ResourceOperationTypeAdapter.java
@@ -0,0 +1,90 @@
+/******************************************************************************
+ * Copyright (c) 2018 Microsoft Corporation and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+
+package org.eclipse.lsp4j.adapters;
+
+import java.io.IOException;
+
+import org.eclipse.lsp4j.CreateFile;
+import org.eclipse.lsp4j.DeleteFile;
+import org.eclipse.lsp4j.RenameFile;
+import org.eclipse.lsp4j.ResourceOperation;
+import org.eclipse.lsp4j.ResourceOperationKind;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import com.google.gson.JsonParser;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+
+public class ResourceOperationTypeAdapter implements TypeAdapterFactory {
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
+
+		if (!ResourceOperation.class.isAssignableFrom(type.getRawType())) {
+			return null;
+		}
+
+		return (TypeAdapter<T>) new InnerResourceOperationTypeAdapter(this, gson).nullSafe();
+	}
+
+	private static class InnerResourceOperationTypeAdapter extends TypeAdapter<ResourceOperation> {
+
+		TypeAdapter<CreateFile> createFileAdapter;
+		TypeAdapter<DeleteFile> deleteFileAdapter;
+		TypeAdapter<RenameFile> renameFileAdapter;
+
+		InnerResourceOperationTypeAdapter(TypeAdapterFactory factory, Gson gson) {
+			createFileAdapter = gson.getDelegateAdapter(factory, TypeToken.get(CreateFile.class));
+			deleteFileAdapter = gson.getDelegateAdapter(factory, TypeToken.get(DeleteFile.class));
+			renameFileAdapter = gson.getDelegateAdapter(factory, TypeToken.get(RenameFile.class));
+		}
+
+		@Override
+		public void write(JsonWriter out, ResourceOperation value) throws IOException {
+			if (value.getClass().isAssignableFrom(CreateFile.class)) {
+				createFileAdapter.write(out, (CreateFile) value);
+			} else if (value.getClass().isAssignableFrom(DeleteFile.class)) {
+				deleteFileAdapter.write(out, (DeleteFile) value);
+			} else if (value.getClass().isAssignableFrom(RenameFile.class)) {
+				renameFileAdapter.write(out, (RenameFile) value);
+			}
+		}
+
+		@Override
+		public ResourceOperation read(JsonReader in) throws IOException {
+			JsonObject objectJson = JsonParser.parseReader(in).getAsJsonObject();
+			JsonElement value = objectJson.get("kind");
+			if (value != null && value.isJsonPrimitive()) {
+				String kindValue = value.getAsString();
+
+				if (ResourceOperationKind.Create.equals(kindValue)) {
+					return createFileAdapter.fromJsonTree(objectJson);
+				} else if (ResourceOperationKind.Delete.equals(kindValue)) {
+					return deleteFileAdapter.fromJsonTree(objectJson);
+				} else if (ResourceOperationKind.Rename.equals(kindValue)) {
+					return renameFileAdapter.fromJsonTree(objectJson);
+				}
+			}
+
+			throw new JsonParseException(
+					"The ResourceOperation object either has null \"kind\" value or the \"kind\" value is not valid.");
+		}
+	}
+}
diff --git a/java/org/eclipse/lsp4j/adapters/SemanticTokensFullDeltaResponseAdapter.java b/java/org/eclipse/lsp4j/adapters/SemanticTokensFullDeltaResponseAdapter.java
new file mode 100644
index 0000000..4850a86
--- /dev/null
+++ b/java/org/eclipse/lsp4j/adapters/SemanticTokensFullDeltaResponseAdapter.java
@@ -0,0 +1,40 @@
+/******************************************************************************
+ * Copyright (c) 2018-2019 Microsoft Corporation and others.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.adapters;
+
+import java.util.function.Predicate;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+
+import org.eclipse.lsp4j.SemanticTokensDelta;
+import org.eclipse.lsp4j.SemanticTokens;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.EitherTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.EitherTypeAdapter.PropertyChecker;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+
+public class SemanticTokensFullDeltaResponseAdapter implements TypeAdapterFactory {
+
+    private static final TypeToken<Either<SemanticTokens, SemanticTokensDelta>> ELEMENT_TYPE
+        = new TypeToken<Either<SemanticTokens, SemanticTokensDelta>>() {};
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
+        Predicate<JsonElement> leftChecker = new PropertyChecker("data");
+        Predicate<JsonElement> rightChecker = new PropertyChecker("edits");
+        return (TypeAdapter<T>) new EitherTypeAdapter<>(gson, ELEMENT_TYPE, leftChecker, rightChecker);
+    }
+}
diff --git a/java/org/eclipse/lsp4j/adapters/SymbolInformationTypeAdapter.java b/java/org/eclipse/lsp4j/adapters/SymbolInformationTypeAdapter.java
new file mode 100644
index 0000000..c62fe93
--- /dev/null
+++ b/java/org/eclipse/lsp4j/adapters/SymbolInformationTypeAdapter.java
@@ -0,0 +1,184 @@
+package org.eclipse.lsp4j.adapters;
+
+import com.google.gson.Gson;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
+import java.util.List;
+import org.eclipse.lsp4j.Location;
+import org.eclipse.lsp4j.Position;
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.SymbolInformation;
+import org.eclipse.lsp4j.SymbolKind;
+import org.eclipse.lsp4j.SymbolTag;
+import org.eclipse.lsp4j.generator.TypeAdapterImpl;
+
+/**
+ * A type adapter for the SymbolInformation protocol type.
+ */
+@TypeAdapterImpl(SymbolInformation.class)
+@SuppressWarnings("all")
+public class SymbolInformationTypeAdapter extends TypeAdapter<SymbolInformation> {
+  public static class Factory implements TypeAdapterFactory {
+    public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> typeToken) {
+      if (!SymbolInformation.class.isAssignableFrom(typeToken.getRawType())) {
+      	return null;
+      }
+      return (TypeAdapter<T>) new SymbolInformationTypeAdapter(gson);
+    }
+  }
+  
+  protected void writeLocation(final JsonWriter out, final Location value) throws IOException {
+    if ((value == null)) {
+      out.nullValue();
+      return;
+    }
+    out.beginObject();
+    out.name("uri");
+    out.value(value.getUri());
+    out.name("range");
+    this.writeRange(out, value.getRange());
+    out.endObject();
+  }
+  
+  protected void writeRange(final JsonWriter out, final Range value) throws IOException {
+    if ((value == null)) {
+      out.nullValue();
+      return;
+    }
+    out.beginObject();
+    out.name("start");
+    this.writePosition(out, value.getStart());
+    out.name("end");
+    this.writePosition(out, value.getEnd());
+    out.endObject();
+  }
+  
+  protected void writePosition(final JsonWriter out, final Position value) throws IOException {
+    if ((value == null)) {
+      out.nullValue();
+      return;
+    }
+    out.beginObject();
+    out.name("line");
+    out.value(value.getLine());
+    out.name("character");
+    out.value(value.getCharacter());
+    out.endObject();
+  }
+  
+  private static final TypeToken<List<SymbolTag>> TAGS_TYPE_TOKEN = new TypeToken<List<SymbolTag>>() {};
+  
+  private final Gson gson;
+  
+  public SymbolInformationTypeAdapter(final Gson gson) {
+    this.gson = gson;
+  }
+  
+  public SymbolInformation read(final JsonReader in) throws IOException {
+    JsonToken nextToken = in.peek();
+    if (nextToken == JsonToken.NULL) {
+    	return null;
+    }
+    
+    SymbolInformation result = new SymbolInformation();
+    in.beginObject();
+    while (in.hasNext()) {
+    	String name = in.nextName();
+    	switch (name) {
+    	case "name":
+    		result.setName(readName(in));
+    		break;
+    	case "kind":
+    		result.setKind(readKind(in));
+    		break;
+    	case "tags":
+    		result.setTags(readTags(in));
+    		break;
+    	case "deprecated":
+    		result.setDeprecated(readDeprecated(in));
+    		break;
+    	case "location":
+    		result.setLocation(readLocation(in));
+    		break;
+    	case "containerName":
+    		result.setContainerName(readContainerName(in));
+    		break;
+    	default:
+    		in.skipValue();
+    	}
+    }
+    in.endObject();
+    return result;
+  }
+  
+  protected String readName(final JsonReader in) throws IOException {
+    return gson.fromJson(in, String.class);
+  }
+  
+  protected SymbolKind readKind(final JsonReader in) throws IOException {
+    return gson.fromJson(in, SymbolKind.class);
+  }
+  
+  protected List<SymbolTag> readTags(final JsonReader in) throws IOException {
+    return gson.fromJson(in, TAGS_TYPE_TOKEN.getType());
+  }
+  
+  protected Boolean readDeprecated(final JsonReader in) throws IOException {
+    return gson.fromJson(in, Boolean.class);
+  }
+  
+  protected Location readLocation(final JsonReader in) throws IOException {
+    return gson.fromJson(in, Location.class);
+  }
+  
+  protected String readContainerName(final JsonReader in) throws IOException {
+    return gson.fromJson(in, String.class);
+  }
+  
+  public void write(final JsonWriter out, final SymbolInformation value) throws IOException {
+    if (value == null) {
+    	out.nullValue();
+    	return;
+    }
+    
+    out.beginObject();
+    out.name("name");
+    writeName(out, value.getName());
+    out.name("kind");
+    writeKind(out, value.getKind());
+    out.name("tags");
+    writeTags(out, value.getTags());
+    out.name("deprecated");
+    writeDeprecated(out, value.getDeprecated());
+    out.name("location");
+    writeLocation(out, value.getLocation());
+    out.name("containerName");
+    writeContainerName(out, value.getContainerName());
+    out.endObject();
+  }
+  
+  protected void writeName(final JsonWriter out, final String value) throws IOException {
+    out.value(value);
+  }
+  
+  protected void writeKind(final JsonWriter out, final SymbolKind value) throws IOException {
+    gson.toJson(value, SymbolKind.class, out);
+  }
+  
+  protected void writeTags(final JsonWriter out, final List<SymbolTag> value) throws IOException {
+    gson.toJson(value, TAGS_TYPE_TOKEN.getType(), out);
+  }
+  
+  protected void writeDeprecated(final JsonWriter out, final Boolean value) throws IOException {
+    out.value(value);
+  }
+  
+  protected void writeContainerName(final JsonWriter out, final String value) throws IOException {
+    out.value(value);
+  }
+}
diff --git a/java/org/eclipse/lsp4j/adapters/SymbolInformationTypeAdapter.xtend b/java/org/eclipse/lsp4j/adapters/SymbolInformationTypeAdapter.xtend
new file mode 100644
index 0000000..d4a594c
--- /dev/null
+++ b/java/org/eclipse/lsp4j/adapters/SymbolInformationTypeAdapter.xtend
@@ -0,0 +1,59 @@
+package org.eclipse.lsp4j.adapters
+
+import com.google.gson.stream.JsonWriter
+import java.io.IOException
+import org.eclipse.lsp4j.Location
+import org.eclipse.lsp4j.Position
+import org.eclipse.lsp4j.Range
+import org.eclipse.lsp4j.SymbolInformation
+import org.eclipse.lsp4j.generator.TypeAdapterImpl
+
+/**
+ * A type adapter for the SymbolInformation protocol type.
+ */
+@TypeAdapterImpl(SymbolInformation)
+class SymbolInformationTypeAdapter {
+	
+	protected def writeLocation(JsonWriter out, Location value) throws IOException {
+		if (value === null) {
+	    	out.nullValue()
+	    	return
+	    }
+	    
+	    out.beginObject()
+	    out.name('uri')
+	    out.value(value.uri)
+	    out.name('range')
+	    writeRange(out, value.range)
+	    out.endObject()
+	}
+	
+	protected def writeRange(JsonWriter out, Range value) throws IOException {
+		if (value === null) {
+	    	out.nullValue()
+	    	return
+	    }
+	    
+	    out.beginObject()
+	    out.name('start')
+	    writePosition(out, value.start)
+	    out.name('end')
+	    writePosition(out, value.end)
+	    out.endObject()
+	}
+	
+	protected def writePosition(JsonWriter out, Position value) throws IOException {
+		if (value === null) {
+	    	out.nullValue()
+	    	return
+	    }
+	    
+	    out.beginObject()
+	    out.name('line')
+	    out.value(value.line)
+	    out.name('character')
+	    out.value(value.character)
+	    out.endObject()
+	}
+	
+}
\ No newline at end of file
diff --git a/java/org/eclipse/lsp4j/adapters/VersionedTextDocumentIdentifierTypeAdapter.java b/java/org/eclipse/lsp4j/adapters/VersionedTextDocumentIdentifierTypeAdapter.java
new file mode 100644
index 0000000..1cbc534
--- /dev/null
+++ b/java/org/eclipse/lsp4j/adapters/VersionedTextDocumentIdentifierTypeAdapter.java
@@ -0,0 +1,107 @@
+/**
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.adapters;
+
+import com.google.gson.Gson;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
+import org.eclipse.lsp4j.VersionedTextDocumentIdentifier;
+import org.eclipse.lsp4j.generator.TypeAdapterImpl;
+
+/**
+ * A type adapter for the VersionedTextDocumentIdentifier protocol type.
+ */
+@TypeAdapterImpl(VersionedTextDocumentIdentifier.class)
+@SuppressWarnings("all")
+public class VersionedTextDocumentIdentifierTypeAdapter extends TypeAdapter<VersionedTextDocumentIdentifier> {
+  public static class Factory implements TypeAdapterFactory {
+    public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> typeToken) {
+      if (!VersionedTextDocumentIdentifier.class.isAssignableFrom(typeToken.getRawType())) {
+      	return null;
+      }
+      return (TypeAdapter<T>) new VersionedTextDocumentIdentifierTypeAdapter(gson);
+    }
+  }
+  
+  protected void writeVersion(final JsonWriter out, final Integer value) throws IOException {
+    if ((value == null)) {
+      final boolean previousSerializeNulls = out.getSerializeNulls();
+      out.setSerializeNulls(true);
+      out.nullValue();
+      out.setSerializeNulls(previousSerializeNulls);
+    } else {
+      out.value(value);
+    }
+  }
+  
+  private final Gson gson;
+  
+  public VersionedTextDocumentIdentifierTypeAdapter(final Gson gson) {
+    this.gson = gson;
+  }
+  
+  public VersionedTextDocumentIdentifier read(final JsonReader in) throws IOException {
+    JsonToken nextToken = in.peek();
+    if (nextToken == JsonToken.NULL) {
+    	return null;
+    }
+    
+    VersionedTextDocumentIdentifier result = new VersionedTextDocumentIdentifier();
+    in.beginObject();
+    while (in.hasNext()) {
+    	String name = in.nextName();
+    	switch (name) {
+    	case "version":
+    		result.setVersion(readVersion(in));
+    		break;
+    	case "uri":
+    		result.setUri(readUri(in));
+    		break;
+    	default:
+    		in.skipValue();
+    	}
+    }
+    in.endObject();
+    return result;
+  }
+  
+  protected Integer readVersion(final JsonReader in) throws IOException {
+    return gson.fromJson(in, Integer.class);
+  }
+  
+  protected String readUri(final JsonReader in) throws IOException {
+    return gson.fromJson(in, String.class);
+  }
+  
+  public void write(final JsonWriter out, final VersionedTextDocumentIdentifier value) throws IOException {
+    if (value == null) {
+    	out.nullValue();
+    	return;
+    }
+    
+    out.beginObject();
+    out.name("version");
+    writeVersion(out, value.getVersion());
+    out.name("uri");
+    writeUri(out, value.getUri());
+    out.endObject();
+  }
+  
+  protected void writeUri(final JsonWriter out, final String value) throws IOException {
+    out.value(value);
+  }
+}
diff --git a/java/org/eclipse/lsp4j/adapters/VersionedTextDocumentIdentifierTypeAdapter.xtend b/java/org/eclipse/lsp4j/adapters/VersionedTextDocumentIdentifierTypeAdapter.xtend
new file mode 100644
index 0000000..ebdcf8b
--- /dev/null
+++ b/java/org/eclipse/lsp4j/adapters/VersionedTextDocumentIdentifierTypeAdapter.xtend
@@ -0,0 +1,36 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.adapters
+
+import com.google.gson.stream.JsonWriter
+import java.io.IOException
+import org.eclipse.lsp4j.VersionedTextDocumentIdentifier
+import org.eclipse.lsp4j.generator.TypeAdapterImpl
+
+/**
+ * A type adapter for the VersionedTextDocumentIdentifier protocol type.
+ */
+@TypeAdapterImpl(VersionedTextDocumentIdentifier)
+class VersionedTextDocumentIdentifierTypeAdapter {
+
+	protected def void writeVersion(JsonWriter out, Integer value) throws IOException {
+		if (value === null) {
+			val previousSerializeNulls = out.serializeNulls
+			out.serializeNulls = true
+			out.nullValue()
+			out.serializeNulls = previousSerializeNulls
+		} else {
+			out.value(value)
+		}
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/adapters/WorkDoneProgressNotificationAdapter.java b/java/org/eclipse/lsp4j/adapters/WorkDoneProgressNotificationAdapter.java
new file mode 100644
index 0000000..44ac0dd
--- /dev/null
+++ b/java/org/eclipse/lsp4j/adapters/WorkDoneProgressNotificationAdapter.java
@@ -0,0 +1,176 @@
+/******************************************************************************
+ * Copyright (c) 2020 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.adapters;
+
+import java.io.EOFException;
+import java.io.IOException;
+
+import org.eclipse.lsp4j.WorkDoneProgressBegin;
+import org.eclipse.lsp4j.WorkDoneProgressEnd;
+import org.eclipse.lsp4j.WorkDoneProgressKind;
+import org.eclipse.lsp4j.WorkDoneProgressNotification;
+import org.eclipse.lsp4j.WorkDoneProgressReport;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonParseException;
+import com.google.gson.JsonSyntaxException;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.JsonWriter;
+import com.google.gson.stream.MalformedJsonException;
+
+/**
+ * A type adapter for class which implements WorkDoneProgressNotification interface.
+ */
+public class WorkDoneProgressNotificationAdapter extends TypeAdapter<WorkDoneProgressNotification> {
+
+	public static class Factory implements TypeAdapterFactory {
+
+		@SuppressWarnings("unchecked")
+		@Override
+		public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
+			Class<?> rawType = typeToken.getRawType();
+			if (!WorkDoneProgressNotification.class.isAssignableFrom(rawType)) {
+				return null;
+			}
+			return (TypeAdapter<T>) new WorkDoneProgressNotificationAdapter();
+		}
+
+	}
+
+	public WorkDoneProgressNotificationAdapter() {
+	}
+
+	@Override
+	public WorkDoneProgressNotification read(JsonReader in) throws IOException {
+		if (in.peek() == JsonToken.NULL) {
+			in.nextNull();
+			return null;
+		}
+		
+		in.beginObject();
+		String kind = null, message = null, title = null;
+		Boolean cancellable = null;
+		Integer percentage = null;
+		try {
+			
+			while (in.hasNext()) {
+				String name = in.nextName();
+				switch (name) {
+				case "kind": {
+					kind = in.nextString();
+					break;
+				}
+				case "title": {
+					title = in.nextString();
+					break;
+				}
+				case "message": {
+					message = in.nextString();
+					break;
+				}
+				case "cancellable": {
+					cancellable = in.nextBoolean();
+					break;
+				}
+				case "percentage": {
+					percentage = in.nextInt();
+					break;
+				}
+				default:
+					in.skipValue();
+				}
+			}
+			in.endObject();
+			return createNotification(kind, message, title, cancellable, percentage);
+			
+		} catch (JsonSyntaxException | MalformedJsonException | EOFException exception) {
+			if (kind != null) {
+				throw new JsonParseException(exception);
+			} else {
+				throw exception;
+			}
+		}
+	}
+
+	private WorkDoneProgressNotification createNotification(String kind, String message, String title,
+			Boolean cancellable, Integer percentage) throws MalformedJsonException {
+		if(kind == null) {
+			throw new MalformedJsonException("Kind of progress notification is empty");
+		}
+		switch (kind) {
+		case "begin":
+			WorkDoneProgressBegin begin = new WorkDoneProgressBegin();
+			begin.setMessage(message);
+			begin.setCancellable(cancellable);
+			begin.setPercentage(percentage);
+			begin.setTitle(title);
+			return begin;
+		case "report":
+			WorkDoneProgressReport report = new WorkDoneProgressReport();
+			report.setMessage(message);
+			report.setCancellable(cancellable);
+			report.setPercentage(percentage);
+			return report;
+		case "end":
+			WorkDoneProgressEnd end = new WorkDoneProgressEnd();
+			end.setMessage(message);
+			return end;
+		default:
+			throw new MalformedJsonException("Kind of progress notification is unknown: "+kind);
+		}
+	}
+
+	@Override
+	public void write(JsonWriter out, WorkDoneProgressNotification notification) throws IOException {
+		out.beginObject();
+		out.name("kind");
+		WorkDoneProgressKind kind = notification.getKind();
+		out.value(kind.toString());
+		
+		switch (kind) {
+		case begin:
+			WorkDoneProgressBegin begin = (WorkDoneProgressBegin) notification;
+			out.name("title");
+			out.value(begin.getTitle());
+			out.name("cancellable");
+			out.value(begin.getCancellable());
+			out.name("message");
+			out.value(begin.getMessage());
+			out.name("percentage");
+			out.value(begin.getPercentage());
+			break;
+		case report:
+			WorkDoneProgressReport report = (WorkDoneProgressReport) notification;
+			out.name("cancellable");
+			out.value(report.getCancellable());
+			out.name("message");
+			out.value(report.getMessage());
+			out.name("percentage");
+			out.value(report.getPercentage());
+			break;
+		case end:
+			WorkDoneProgressEnd end = (WorkDoneProgressEnd) notification;
+			out.name("message");
+			out.value(end.getMessage());
+			break;
+
+		default:
+			throw new MalformedJsonException("Kind of progress notification is unknown: "+kind);
+		}
+		out.endObject();
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/debug/AttachRequestArguments.java b/java/org/eclipse/lsp4j/debug/AttachRequestArguments.java
new file mode 100644
index 0000000..cd720ca
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/AttachRequestArguments.java
@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'attach' request. Additional attributes are implementation specific.
+ */
+@SuppressWarnings("all")
+public class AttachRequestArguments {
+  /**
+   * Optional data from the previous, restarted session.
+   * <p>
+   * The data is sent as the 'restart' attribute of the 'terminated' event.
+   * <p>
+   * The client should leave the data intact.
+   * <p>
+   * This is an optional property.
+   */
+  private Object __restart;
+  
+  /**
+   * Optional data from the previous, restarted session.
+   * <p>
+   * The data is sent as the 'restart' attribute of the 'terminated' event.
+   * <p>
+   * The client should leave the data intact.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Object get__restart() {
+    return this.__restart;
+  }
+  
+  /**
+   * Optional data from the previous, restarted session.
+   * <p>
+   * The data is sent as the 'restart' attribute of the 'terminated' event.
+   * <p>
+   * The client should leave the data intact.
+   * <p>
+   * This is an optional property.
+   */
+  public void set__restart(final Object __restart) {
+    this.__restart = __restart;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("__restart", this.__restart);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    AttachRequestArguments other = (AttachRequestArguments) obj;
+    if (this.__restart == null) {
+      if (other.__restart != null)
+        return false;
+    } else if (!this.__restart.equals(other.__restart))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.__restart== null) ? 0 : this.__restart.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/Breakpoint.java b/java/org/eclipse/lsp4j/debug/Breakpoint.java
new file mode 100644
index 0000000..4b84205
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/Breakpoint.java
@@ -0,0 +1,392 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.Source;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Information about a Breakpoint created in setBreakpoints, setFunctionBreakpoints, setInstructionBreakpoints, or
+ * setDataBreakpoints.
+ */
+@SuppressWarnings("all")
+public class Breakpoint {
+  /**
+   * An optional identifier for the breakpoint. It is needed if breakpoint events are used to update or remove
+   * breakpoints.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer id;
+  
+  /**
+   * If true breakpoint could be set (but not necessarily at the desired location).
+   */
+  private boolean verified;
+  
+  /**
+   * An optional message about the state of the breakpoint.
+   * <p>
+   * This is shown to the user and can be used to explain why a breakpoint could not be verified.
+   * <p>
+   * This is an optional property.
+   */
+  private String message;
+  
+  /**
+   * The source where the breakpoint is located.
+   * <p>
+   * This is an optional property.
+   */
+  private Source source;
+  
+  /**
+   * The start line of the actual range covered by the breakpoint.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer line;
+  
+  /**
+   * An optional start column of the actual range covered by the breakpoint.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer column;
+  
+  /**
+   * An optional end line of the actual range covered by the breakpoint.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer endLine;
+  
+  /**
+   * An optional end column of the actual range covered by the breakpoint.
+   * <p>
+   * If no end line is given, then the end column is assumed to be in the start line.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer endColumn;
+  
+  /**
+   * An optional memory reference to where the breakpoint is set.
+   * <p>
+   * This is an optional property.
+   */
+  private String instructionReference;
+  
+  /**
+   * An optional offset from the instruction reference.
+   * <p>
+   * This can be negative.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer offset;
+  
+  /**
+   * An optional identifier for the breakpoint. It is needed if breakpoint events are used to update or remove
+   * breakpoints.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getId() {
+    return this.id;
+  }
+  
+  /**
+   * An optional identifier for the breakpoint. It is needed if breakpoint events are used to update or remove
+   * breakpoints.
+   * <p>
+   * This is an optional property.
+   */
+  public void setId(final Integer id) {
+    this.id = id;
+  }
+  
+  /**
+   * If true breakpoint could be set (but not necessarily at the desired location).
+   */
+  @Pure
+  public boolean isVerified() {
+    return this.verified;
+  }
+  
+  /**
+   * If true breakpoint could be set (but not necessarily at the desired location).
+   */
+  public void setVerified(final boolean verified) {
+    this.verified = verified;
+  }
+  
+  /**
+   * An optional message about the state of the breakpoint.
+   * <p>
+   * This is shown to the user and can be used to explain why a breakpoint could not be verified.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getMessage() {
+    return this.message;
+  }
+  
+  /**
+   * An optional message about the state of the breakpoint.
+   * <p>
+   * This is shown to the user and can be used to explain why a breakpoint could not be verified.
+   * <p>
+   * This is an optional property.
+   */
+  public void setMessage(final String message) {
+    this.message = message;
+  }
+  
+  /**
+   * The source where the breakpoint is located.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Source getSource() {
+    return this.source;
+  }
+  
+  /**
+   * The source where the breakpoint is located.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSource(final Source source) {
+    this.source = source;
+  }
+  
+  /**
+   * The start line of the actual range covered by the breakpoint.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getLine() {
+    return this.line;
+  }
+  
+  /**
+   * The start line of the actual range covered by the breakpoint.
+   * <p>
+   * This is an optional property.
+   */
+  public void setLine(final Integer line) {
+    this.line = line;
+  }
+  
+  /**
+   * An optional start column of the actual range covered by the breakpoint.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getColumn() {
+    return this.column;
+  }
+  
+  /**
+   * An optional start column of the actual range covered by the breakpoint.
+   * <p>
+   * This is an optional property.
+   */
+  public void setColumn(final Integer column) {
+    this.column = column;
+  }
+  
+  /**
+   * An optional end line of the actual range covered by the breakpoint.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getEndLine() {
+    return this.endLine;
+  }
+  
+  /**
+   * An optional end line of the actual range covered by the breakpoint.
+   * <p>
+   * This is an optional property.
+   */
+  public void setEndLine(final Integer endLine) {
+    this.endLine = endLine;
+  }
+  
+  /**
+   * An optional end column of the actual range covered by the breakpoint.
+   * <p>
+   * If no end line is given, then the end column is assumed to be in the start line.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getEndColumn() {
+    return this.endColumn;
+  }
+  
+  /**
+   * An optional end column of the actual range covered by the breakpoint.
+   * <p>
+   * If no end line is given, then the end column is assumed to be in the start line.
+   * <p>
+   * This is an optional property.
+   */
+  public void setEndColumn(final Integer endColumn) {
+    this.endColumn = endColumn;
+  }
+  
+  /**
+   * An optional memory reference to where the breakpoint is set.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getInstructionReference() {
+    return this.instructionReference;
+  }
+  
+  /**
+   * An optional memory reference to where the breakpoint is set.
+   * <p>
+   * This is an optional property.
+   */
+  public void setInstructionReference(final String instructionReference) {
+    this.instructionReference = instructionReference;
+  }
+  
+  /**
+   * An optional offset from the instruction reference.
+   * <p>
+   * This can be negative.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getOffset() {
+    return this.offset;
+  }
+  
+  /**
+   * An optional offset from the instruction reference.
+   * <p>
+   * This can be negative.
+   * <p>
+   * This is an optional property.
+   */
+  public void setOffset(final Integer offset) {
+    this.offset = offset;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("id", this.id);
+    b.add("verified", this.verified);
+    b.add("message", this.message);
+    b.add("source", this.source);
+    b.add("line", this.line);
+    b.add("column", this.column);
+    b.add("endLine", this.endLine);
+    b.add("endColumn", this.endColumn);
+    b.add("instructionReference", this.instructionReference);
+    b.add("offset", this.offset);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    Breakpoint other = (Breakpoint) obj;
+    if (this.id == null) {
+      if (other.id != null)
+        return false;
+    } else if (!this.id.equals(other.id))
+      return false;
+    if (other.verified != this.verified)
+      return false;
+    if (this.message == null) {
+      if (other.message != null)
+        return false;
+    } else if (!this.message.equals(other.message))
+      return false;
+    if (this.source == null) {
+      if (other.source != null)
+        return false;
+    } else if (!this.source.equals(other.source))
+      return false;
+    if (this.line == null) {
+      if (other.line != null)
+        return false;
+    } else if (!this.line.equals(other.line))
+      return false;
+    if (this.column == null) {
+      if (other.column != null)
+        return false;
+    } else if (!this.column.equals(other.column))
+      return false;
+    if (this.endLine == null) {
+      if (other.endLine != null)
+        return false;
+    } else if (!this.endLine.equals(other.endLine))
+      return false;
+    if (this.endColumn == null) {
+      if (other.endColumn != null)
+        return false;
+    } else if (!this.endColumn.equals(other.endColumn))
+      return false;
+    if (this.instructionReference == null) {
+      if (other.instructionReference != null)
+        return false;
+    } else if (!this.instructionReference.equals(other.instructionReference))
+      return false;
+    if (this.offset == null) {
+      if (other.offset != null)
+        return false;
+    } else if (!this.offset.equals(other.offset))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.id== null) ? 0 : this.id.hashCode());
+    result = prime * result + (this.verified ? 1231 : 1237);
+    result = prime * result + ((this.message== null) ? 0 : this.message.hashCode());
+    result = prime * result + ((this.source== null) ? 0 : this.source.hashCode());
+    result = prime * result + ((this.line== null) ? 0 : this.line.hashCode());
+    result = prime * result + ((this.column== null) ? 0 : this.column.hashCode());
+    result = prime * result + ((this.endLine== null) ? 0 : this.endLine.hashCode());
+    result = prime * result + ((this.endColumn== null) ? 0 : this.endColumn.hashCode());
+    result = prime * result + ((this.instructionReference== null) ? 0 : this.instructionReference.hashCode());
+    return prime * result + ((this.offset== null) ? 0 : this.offset.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/BreakpointEventArguments.java b/java/org/eclipse/lsp4j/debug/BreakpointEventArguments.java
new file mode 100644
index 0000000..a589403
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/BreakpointEventArguments.java
@@ -0,0 +1,115 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.Breakpoint;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The event indicates that some information about a breakpoint has changed.
+ */
+@SuppressWarnings("all")
+public class BreakpointEventArguments {
+  /**
+   * The reason for the event.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link BreakpointEventArgumentsReason}
+   */
+  @NonNull
+  private String reason;
+  
+  /**
+   * The 'id' attribute is used to find the target breakpoint and the other attributes are used as the new values.
+   */
+  @NonNull
+  private Breakpoint breakpoint;
+  
+  /**
+   * The reason for the event.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link BreakpointEventArgumentsReason}
+   */
+  @Pure
+  @NonNull
+  public String getReason() {
+    return this.reason;
+  }
+  
+  /**
+   * The reason for the event.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link BreakpointEventArgumentsReason}
+   */
+  public void setReason(@NonNull final String reason) {
+    this.reason = Preconditions.checkNotNull(reason, "reason");
+  }
+  
+  /**
+   * The 'id' attribute is used to find the target breakpoint and the other attributes are used as the new values.
+   */
+  @Pure
+  @NonNull
+  public Breakpoint getBreakpoint() {
+    return this.breakpoint;
+  }
+  
+  /**
+   * The 'id' attribute is used to find the target breakpoint and the other attributes are used as the new values.
+   */
+  public void setBreakpoint(@NonNull final Breakpoint breakpoint) {
+    this.breakpoint = Preconditions.checkNotNull(breakpoint, "breakpoint");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("reason", this.reason);
+    b.add("breakpoint", this.breakpoint);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    BreakpointEventArguments other = (BreakpointEventArguments) obj;
+    if (this.reason == null) {
+      if (other.reason != null)
+        return false;
+    } else if (!this.reason.equals(other.reason))
+      return false;
+    if (this.breakpoint == null) {
+      if (other.breakpoint != null)
+        return false;
+    } else if (!this.breakpoint.equals(other.breakpoint))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.reason== null) ? 0 : this.reason.hashCode());
+    return prime * result + ((this.breakpoint== null) ? 0 : this.breakpoint.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/BreakpointEventArgumentsReason.java b/java/org/eclipse/lsp4j/debug/BreakpointEventArgumentsReason.java
new file mode 100644
index 0000000..4b6076d
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/BreakpointEventArgumentsReason.java
@@ -0,0 +1,26 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+/**
+ * The reason for the event.
+ * <p>
+ * Possible values include - but not limited to those defined in {@link BreakpointEventArgumentsReason}
+ */
+@SuppressWarnings("all")
+public interface BreakpointEventArgumentsReason {
+  static final String CHANGED = "changed";
+  
+  static final String NEW = "new";
+  
+  static final String REMOVED = "removed";
+}
diff --git a/java/org/eclipse/lsp4j/debug/BreakpointLocation.java b/java/org/eclipse/lsp4j/debug/BreakpointLocation.java
new file mode 100644
index 0000000..8c79738
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/BreakpointLocation.java
@@ -0,0 +1,171 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Properties of a breakpoint location returned from the 'breakpointLocations' request.
+ */
+@SuppressWarnings("all")
+public class BreakpointLocation {
+  /**
+   * Start line of breakpoint location.
+   */
+  private int line;
+  
+  /**
+   * Optional start column of breakpoint location.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer column;
+  
+  /**
+   * Optional end line of breakpoint location if the location covers a range.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer endLine;
+  
+  /**
+   * Optional end column of breakpoint location if the location covers a range.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer endColumn;
+  
+  /**
+   * Start line of breakpoint location.
+   */
+  @Pure
+  public int getLine() {
+    return this.line;
+  }
+  
+  /**
+   * Start line of breakpoint location.
+   */
+  public void setLine(final int line) {
+    this.line = line;
+  }
+  
+  /**
+   * Optional start column of breakpoint location.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getColumn() {
+    return this.column;
+  }
+  
+  /**
+   * Optional start column of breakpoint location.
+   * <p>
+   * This is an optional property.
+   */
+  public void setColumn(final Integer column) {
+    this.column = column;
+  }
+  
+  /**
+   * Optional end line of breakpoint location if the location covers a range.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getEndLine() {
+    return this.endLine;
+  }
+  
+  /**
+   * Optional end line of breakpoint location if the location covers a range.
+   * <p>
+   * This is an optional property.
+   */
+  public void setEndLine(final Integer endLine) {
+    this.endLine = endLine;
+  }
+  
+  /**
+   * Optional end column of breakpoint location if the location covers a range.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getEndColumn() {
+    return this.endColumn;
+  }
+  
+  /**
+   * Optional end column of breakpoint location if the location covers a range.
+   * <p>
+   * This is an optional property.
+   */
+  public void setEndColumn(final Integer endColumn) {
+    this.endColumn = endColumn;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("line", this.line);
+    b.add("column", this.column);
+    b.add("endLine", this.endLine);
+    b.add("endColumn", this.endColumn);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    BreakpointLocation other = (BreakpointLocation) obj;
+    if (other.line != this.line)
+      return false;
+    if (this.column == null) {
+      if (other.column != null)
+        return false;
+    } else if (!this.column.equals(other.column))
+      return false;
+    if (this.endLine == null) {
+      if (other.endLine != null)
+        return false;
+    } else if (!this.endLine.equals(other.endLine))
+      return false;
+    if (this.endColumn == null) {
+      if (other.endColumn != null)
+        return false;
+    } else if (!this.endColumn.equals(other.endColumn))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + this.line;
+    result = prime * result + ((this.column== null) ? 0 : this.column.hashCode());
+    result = prime * result + ((this.endLine== null) ? 0 : this.endLine.hashCode());
+    return prime * result + ((this.endColumn== null) ? 0 : this.endColumn.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/BreakpointLocationsArguments.java b/java/org/eclipse/lsp4j/debug/BreakpointLocationsArguments.java
new file mode 100644
index 0000000..14ce2a5
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/BreakpointLocationsArguments.java
@@ -0,0 +1,215 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.Source;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'breakpointLocations' request.
+ */
+@SuppressWarnings("all")
+public class BreakpointLocationsArguments {
+  /**
+   * The source location of the breakpoints; either 'source.path' or 'source.reference' must be specified.
+   */
+  @NonNull
+  private Source source;
+  
+  /**
+   * Start line of range to search possible breakpoint locations in. If only the line is specified, the request
+   * returns all possible locations in that line.
+   */
+  private int line;
+  
+  /**
+   * Optional start column of range to search possible breakpoint locations in. If no start column is given, the
+   * first column in the start line is assumed.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer column;
+  
+  /**
+   * Optional end line of range to search possible breakpoint locations in. If no end line is given, then the end
+   * line is assumed to be the start line.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer endLine;
+  
+  /**
+   * Optional end column of range to search possible breakpoint locations in. If no end column is given, then it is
+   * assumed to be in the last column of the end line.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer endColumn;
+  
+  /**
+   * The source location of the breakpoints; either 'source.path' or 'source.reference' must be specified.
+   */
+  @Pure
+  @NonNull
+  public Source getSource() {
+    return this.source;
+  }
+  
+  /**
+   * The source location of the breakpoints; either 'source.path' or 'source.reference' must be specified.
+   */
+  public void setSource(@NonNull final Source source) {
+    this.source = Preconditions.checkNotNull(source, "source");
+  }
+  
+  /**
+   * Start line of range to search possible breakpoint locations in. If only the line is specified, the request
+   * returns all possible locations in that line.
+   */
+  @Pure
+  public int getLine() {
+    return this.line;
+  }
+  
+  /**
+   * Start line of range to search possible breakpoint locations in. If only the line is specified, the request
+   * returns all possible locations in that line.
+   */
+  public void setLine(final int line) {
+    this.line = line;
+  }
+  
+  /**
+   * Optional start column of range to search possible breakpoint locations in. If no start column is given, the
+   * first column in the start line is assumed.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getColumn() {
+    return this.column;
+  }
+  
+  /**
+   * Optional start column of range to search possible breakpoint locations in. If no start column is given, the
+   * first column in the start line is assumed.
+   * <p>
+   * This is an optional property.
+   */
+  public void setColumn(final Integer column) {
+    this.column = column;
+  }
+  
+  /**
+   * Optional end line of range to search possible breakpoint locations in. If no end line is given, then the end
+   * line is assumed to be the start line.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getEndLine() {
+    return this.endLine;
+  }
+  
+  /**
+   * Optional end line of range to search possible breakpoint locations in. If no end line is given, then the end
+   * line is assumed to be the start line.
+   * <p>
+   * This is an optional property.
+   */
+  public void setEndLine(final Integer endLine) {
+    this.endLine = endLine;
+  }
+  
+  /**
+   * Optional end column of range to search possible breakpoint locations in. If no end column is given, then it is
+   * assumed to be in the last column of the end line.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getEndColumn() {
+    return this.endColumn;
+  }
+  
+  /**
+   * Optional end column of range to search possible breakpoint locations in. If no end column is given, then it is
+   * assumed to be in the last column of the end line.
+   * <p>
+   * This is an optional property.
+   */
+  public void setEndColumn(final Integer endColumn) {
+    this.endColumn = endColumn;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("source", this.source);
+    b.add("line", this.line);
+    b.add("column", this.column);
+    b.add("endLine", this.endLine);
+    b.add("endColumn", this.endColumn);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    BreakpointLocationsArguments other = (BreakpointLocationsArguments) obj;
+    if (this.source == null) {
+      if (other.source != null)
+        return false;
+    } else if (!this.source.equals(other.source))
+      return false;
+    if (other.line != this.line)
+      return false;
+    if (this.column == null) {
+      if (other.column != null)
+        return false;
+    } else if (!this.column.equals(other.column))
+      return false;
+    if (this.endLine == null) {
+      if (other.endLine != null)
+        return false;
+    } else if (!this.endLine.equals(other.endLine))
+      return false;
+    if (this.endColumn == null) {
+      if (other.endColumn != null)
+        return false;
+    } else if (!this.endColumn.equals(other.endColumn))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.source== null) ? 0 : this.source.hashCode());
+    result = prime * result + this.line;
+    result = prime * result + ((this.column== null) ? 0 : this.column.hashCode());
+    result = prime * result + ((this.endLine== null) ? 0 : this.endLine.hashCode());
+    return prime * result + ((this.endColumn== null) ? 0 : this.endColumn.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/BreakpointLocationsResponse.java b/java/org/eclipse/lsp4j/debug/BreakpointLocationsResponse.java
new file mode 100644
index 0000000..72f572a
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/BreakpointLocationsResponse.java
@@ -0,0 +1,81 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.lsp4j.debug.BreakpointLocation;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Response to 'breakpointLocations' request.
+ * <p>
+ * Contains possible locations for source breakpoints.
+ */
+@SuppressWarnings("all")
+public class BreakpointLocationsResponse {
+  /**
+   * Sorted set of possible breakpoint locations.
+   */
+  @NonNull
+  private BreakpointLocation[] breakpoints;
+  
+  /**
+   * Sorted set of possible breakpoint locations.
+   */
+  @Pure
+  @NonNull
+  public BreakpointLocation[] getBreakpoints() {
+    return this.breakpoints;
+  }
+  
+  /**
+   * Sorted set of possible breakpoint locations.
+   */
+  public void setBreakpoints(@NonNull final BreakpointLocation[] breakpoints) {
+    this.breakpoints = Preconditions.checkNotNull(breakpoints, "breakpoints");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("breakpoints", this.breakpoints);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    BreakpointLocationsResponse other = (BreakpointLocationsResponse) obj;
+    if (this.breakpoints == null) {
+      if (other.breakpoints != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.breakpoints, other.breakpoints))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.breakpoints== null) ? 0 : Arrays.deepHashCode(this.breakpoints));
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/CancelArguments.java b/java/org/eclipse/lsp4j/debug/CancelArguments.java
new file mode 100644
index 0000000..05a97d4
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/CancelArguments.java
@@ -0,0 +1,126 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'cancel' request.
+ */
+@SuppressWarnings("all")
+public class CancelArguments {
+  /**
+   * The ID (attribute 'seq') of the request to cancel. If missing no request is cancelled.
+   * <p>
+   * Both a 'requestId' and a 'progressId' can be specified in one request.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer requestId;
+  
+  /**
+   * The ID (attribute 'progressId') of the progress to cancel. If missing no progress is cancelled.
+   * <p>
+   * Both a 'requestId' and a 'progressId' can be specified in one request.
+   * <p>
+   * This is an optional property.
+   */
+  private String progressId;
+  
+  /**
+   * The ID (attribute 'seq') of the request to cancel. If missing no request is cancelled.
+   * <p>
+   * Both a 'requestId' and a 'progressId' can be specified in one request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getRequestId() {
+    return this.requestId;
+  }
+  
+  /**
+   * The ID (attribute 'seq') of the request to cancel. If missing no request is cancelled.
+   * <p>
+   * Both a 'requestId' and a 'progressId' can be specified in one request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setRequestId(final Integer requestId) {
+    this.requestId = requestId;
+  }
+  
+  /**
+   * The ID (attribute 'progressId') of the progress to cancel. If missing no progress is cancelled.
+   * <p>
+   * Both a 'requestId' and a 'progressId' can be specified in one request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getProgressId() {
+    return this.progressId;
+  }
+  
+  /**
+   * The ID (attribute 'progressId') of the progress to cancel. If missing no progress is cancelled.
+   * <p>
+   * Both a 'requestId' and a 'progressId' can be specified in one request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setProgressId(final String progressId) {
+    this.progressId = progressId;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("requestId", this.requestId);
+    b.add("progressId", this.progressId);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CancelArguments other = (CancelArguments) obj;
+    if (this.requestId == null) {
+      if (other.requestId != null)
+        return false;
+    } else if (!this.requestId.equals(other.requestId))
+      return false;
+    if (this.progressId == null) {
+      if (other.progressId != null)
+        return false;
+    } else if (!this.progressId.equals(other.progressId))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.requestId== null) ? 0 : this.requestId.hashCode());
+    return prime * result + ((this.progressId== null) ? 0 : this.progressId.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/Capabilities.java b/java/org/eclipse/lsp4j/debug/Capabilities.java
new file mode 100644
index 0000000..07adbb9
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/Capabilities.java
@@ -0,0 +1,1252 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.lsp4j.debug.ChecksumAlgorithm;
+import org.eclipse.lsp4j.debug.ColumnDescriptor;
+import org.eclipse.lsp4j.debug.ExceptionBreakpointsFilter;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Information about the capabilities of a debug adapter.
+ */
+@SuppressWarnings("all")
+public class Capabilities {
+  /**
+   * The debug adapter supports the 'configurationDone' request.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsConfigurationDoneRequest;
+  
+  /**
+   * The debug adapter supports function breakpoints.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsFunctionBreakpoints;
+  
+  /**
+   * The debug adapter supports conditional breakpoints.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsConditionalBreakpoints;
+  
+  /**
+   * The debug adapter supports breakpoints that break execution after a specified number of hits.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsHitConditionalBreakpoints;
+  
+  /**
+   * The debug adapter supports a (side effect free) evaluate request for data hovers.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsEvaluateForHovers;
+  
+  /**
+   * Available exception filter options for the 'setExceptionBreakpoints' request.
+   * <p>
+   * This is an optional property.
+   */
+  private ExceptionBreakpointsFilter[] exceptionBreakpointFilters;
+  
+  /**
+   * The debug adapter supports stepping back via the 'stepBack' and 'reverseContinue' requests.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsStepBack;
+  
+  /**
+   * The debug adapter supports setting a variable to a value.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsSetVariable;
+  
+  /**
+   * The debug adapter supports restarting a frame.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsRestartFrame;
+  
+  /**
+   * The debug adapter supports the 'gotoTargets' request.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsGotoTargetsRequest;
+  
+  /**
+   * The debug adapter supports the 'stepInTargets' request.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsStepInTargetsRequest;
+  
+  /**
+   * The debug adapter supports the 'completions' request.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsCompletionsRequest;
+  
+  /**
+   * The set of characters that should trigger completion in a REPL. If not specified, the UI should assume the '.'
+   * character.
+   * <p>
+   * This is an optional property.
+   */
+  private String[] completionTriggerCharacters;
+  
+  /**
+   * The debug adapter supports the 'modules' request.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsModulesRequest;
+  
+  /**
+   * The set of additional module information exposed by the debug adapter.
+   * <p>
+   * This is an optional property.
+   */
+  private ColumnDescriptor[] additionalModuleColumns;
+  
+  /**
+   * Checksum algorithms supported by the debug adapter.
+   * <p>
+   * This is an optional property.
+   */
+  private ChecksumAlgorithm[] supportedChecksumAlgorithms;
+  
+  /**
+   * The debug adapter supports the 'restart' request. In this case a client should not implement 'restart' by
+   * terminating and relaunching the adapter but by calling the RestartRequest.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsRestartRequest;
+  
+  /**
+   * The debug adapter supports 'exceptionOptions' on the setExceptionBreakpoints request.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsExceptionOptions;
+  
+  /**
+   * The debug adapter supports a 'format' attribute on the stackTraceRequest, variablesRequest, and
+   * evaluateRequest.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsValueFormattingOptions;
+  
+  /**
+   * The debug adapter supports the 'exceptionInfo' request.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsExceptionInfoRequest;
+  
+  /**
+   * The debug adapter supports the 'terminateDebuggee' attribute on the 'disconnect' request.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportTerminateDebuggee;
+  
+  /**
+   * The debug adapter supports the delayed loading of parts of the stack, which requires that both the 'startFrame'
+   * and 'levels' arguments and an optional 'totalFrames' result of the 'StackTrace' request are supported.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsDelayedStackTraceLoading;
+  
+  /**
+   * The debug adapter supports the 'loadedSources' request.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsLoadedSourcesRequest;
+  
+  /**
+   * The debug adapter supports logpoints by interpreting the 'logMessage' attribute of the SourceBreakpoint.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsLogPoints;
+  
+  /**
+   * The debug adapter supports the 'terminateThreads' request.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsTerminateThreadsRequest;
+  
+  /**
+   * The debug adapter supports the 'setExpression' request.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsSetExpression;
+  
+  /**
+   * The debug adapter supports the 'terminate' request.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsTerminateRequest;
+  
+  /**
+   * The debug adapter supports data breakpoints.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsDataBreakpoints;
+  
+  /**
+   * The debug adapter supports the 'readMemory' request.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsReadMemoryRequest;
+  
+  /**
+   * The debug adapter supports the 'disassemble' request.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsDisassembleRequest;
+  
+  /**
+   * The debug adapter supports the 'cancel' request.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsCancelRequest;
+  
+  /**
+   * The debug adapter supports the 'breakpointLocations' request.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsBreakpointLocationsRequest;
+  
+  /**
+   * The debug adapter supports the 'clipboard' context value in the 'evaluate' request.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsClipboardContext;
+  
+  /**
+   * The debug adapter supports stepping granularities (argument 'granularity') for the stepping requests.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsSteppingGranularity;
+  
+  /**
+   * The debug adapter supports adding breakpoints based on instruction references.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsInstructionBreakpoints;
+  
+  /**
+   * The debug adapter supports 'filterOptions' as an argument on the 'setExceptionBreakpoints' request.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsExceptionFilterOptions;
+  
+  /**
+   * The debug adapter supports the 'configurationDone' request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsConfigurationDoneRequest() {
+    return this.supportsConfigurationDoneRequest;
+  }
+  
+  /**
+   * The debug adapter supports the 'configurationDone' request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsConfigurationDoneRequest(final Boolean supportsConfigurationDoneRequest) {
+    this.supportsConfigurationDoneRequest = supportsConfigurationDoneRequest;
+  }
+  
+  /**
+   * The debug adapter supports function breakpoints.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsFunctionBreakpoints() {
+    return this.supportsFunctionBreakpoints;
+  }
+  
+  /**
+   * The debug adapter supports function breakpoints.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsFunctionBreakpoints(final Boolean supportsFunctionBreakpoints) {
+    this.supportsFunctionBreakpoints = supportsFunctionBreakpoints;
+  }
+  
+  /**
+   * The debug adapter supports conditional breakpoints.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsConditionalBreakpoints() {
+    return this.supportsConditionalBreakpoints;
+  }
+  
+  /**
+   * The debug adapter supports conditional breakpoints.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsConditionalBreakpoints(final Boolean supportsConditionalBreakpoints) {
+    this.supportsConditionalBreakpoints = supportsConditionalBreakpoints;
+  }
+  
+  /**
+   * The debug adapter supports breakpoints that break execution after a specified number of hits.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsHitConditionalBreakpoints() {
+    return this.supportsHitConditionalBreakpoints;
+  }
+  
+  /**
+   * The debug adapter supports breakpoints that break execution after a specified number of hits.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsHitConditionalBreakpoints(final Boolean supportsHitConditionalBreakpoints) {
+    this.supportsHitConditionalBreakpoints = supportsHitConditionalBreakpoints;
+  }
+  
+  /**
+   * The debug adapter supports a (side effect free) evaluate request for data hovers.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsEvaluateForHovers() {
+    return this.supportsEvaluateForHovers;
+  }
+  
+  /**
+   * The debug adapter supports a (side effect free) evaluate request for data hovers.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsEvaluateForHovers(final Boolean supportsEvaluateForHovers) {
+    this.supportsEvaluateForHovers = supportsEvaluateForHovers;
+  }
+  
+  /**
+   * Available exception filter options for the 'setExceptionBreakpoints' request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public ExceptionBreakpointsFilter[] getExceptionBreakpointFilters() {
+    return this.exceptionBreakpointFilters;
+  }
+  
+  /**
+   * Available exception filter options for the 'setExceptionBreakpoints' request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setExceptionBreakpointFilters(final ExceptionBreakpointsFilter[] exceptionBreakpointFilters) {
+    this.exceptionBreakpointFilters = exceptionBreakpointFilters;
+  }
+  
+  /**
+   * The debug adapter supports stepping back via the 'stepBack' and 'reverseContinue' requests.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsStepBack() {
+    return this.supportsStepBack;
+  }
+  
+  /**
+   * The debug adapter supports stepping back via the 'stepBack' and 'reverseContinue' requests.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsStepBack(final Boolean supportsStepBack) {
+    this.supportsStepBack = supportsStepBack;
+  }
+  
+  /**
+   * The debug adapter supports setting a variable to a value.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsSetVariable() {
+    return this.supportsSetVariable;
+  }
+  
+  /**
+   * The debug adapter supports setting a variable to a value.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsSetVariable(final Boolean supportsSetVariable) {
+    this.supportsSetVariable = supportsSetVariable;
+  }
+  
+  /**
+   * The debug adapter supports restarting a frame.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsRestartFrame() {
+    return this.supportsRestartFrame;
+  }
+  
+  /**
+   * The debug adapter supports restarting a frame.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsRestartFrame(final Boolean supportsRestartFrame) {
+    this.supportsRestartFrame = supportsRestartFrame;
+  }
+  
+  /**
+   * The debug adapter supports the 'gotoTargets' request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsGotoTargetsRequest() {
+    return this.supportsGotoTargetsRequest;
+  }
+  
+  /**
+   * The debug adapter supports the 'gotoTargets' request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsGotoTargetsRequest(final Boolean supportsGotoTargetsRequest) {
+    this.supportsGotoTargetsRequest = supportsGotoTargetsRequest;
+  }
+  
+  /**
+   * The debug adapter supports the 'stepInTargets' request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsStepInTargetsRequest() {
+    return this.supportsStepInTargetsRequest;
+  }
+  
+  /**
+   * The debug adapter supports the 'stepInTargets' request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsStepInTargetsRequest(final Boolean supportsStepInTargetsRequest) {
+    this.supportsStepInTargetsRequest = supportsStepInTargetsRequest;
+  }
+  
+  /**
+   * The debug adapter supports the 'completions' request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsCompletionsRequest() {
+    return this.supportsCompletionsRequest;
+  }
+  
+  /**
+   * The debug adapter supports the 'completions' request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsCompletionsRequest(final Boolean supportsCompletionsRequest) {
+    this.supportsCompletionsRequest = supportsCompletionsRequest;
+  }
+  
+  /**
+   * The set of characters that should trigger completion in a REPL. If not specified, the UI should assume the '.'
+   * character.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String[] getCompletionTriggerCharacters() {
+    return this.completionTriggerCharacters;
+  }
+  
+  /**
+   * The set of characters that should trigger completion in a REPL. If not specified, the UI should assume the '.'
+   * character.
+   * <p>
+   * This is an optional property.
+   */
+  public void setCompletionTriggerCharacters(final String[] completionTriggerCharacters) {
+    this.completionTriggerCharacters = completionTriggerCharacters;
+  }
+  
+  /**
+   * The debug adapter supports the 'modules' request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsModulesRequest() {
+    return this.supportsModulesRequest;
+  }
+  
+  /**
+   * The debug adapter supports the 'modules' request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsModulesRequest(final Boolean supportsModulesRequest) {
+    this.supportsModulesRequest = supportsModulesRequest;
+  }
+  
+  /**
+   * The set of additional module information exposed by the debug adapter.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public ColumnDescriptor[] getAdditionalModuleColumns() {
+    return this.additionalModuleColumns;
+  }
+  
+  /**
+   * The set of additional module information exposed by the debug adapter.
+   * <p>
+   * This is an optional property.
+   */
+  public void setAdditionalModuleColumns(final ColumnDescriptor[] additionalModuleColumns) {
+    this.additionalModuleColumns = additionalModuleColumns;
+  }
+  
+  /**
+   * Checksum algorithms supported by the debug adapter.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public ChecksumAlgorithm[] getSupportedChecksumAlgorithms() {
+    return this.supportedChecksumAlgorithms;
+  }
+  
+  /**
+   * Checksum algorithms supported by the debug adapter.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportedChecksumAlgorithms(final ChecksumAlgorithm[] supportedChecksumAlgorithms) {
+    this.supportedChecksumAlgorithms = supportedChecksumAlgorithms;
+  }
+  
+  /**
+   * The debug adapter supports the 'restart' request. In this case a client should not implement 'restart' by
+   * terminating and relaunching the adapter but by calling the RestartRequest.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsRestartRequest() {
+    return this.supportsRestartRequest;
+  }
+  
+  /**
+   * The debug adapter supports the 'restart' request. In this case a client should not implement 'restart' by
+   * terminating and relaunching the adapter but by calling the RestartRequest.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsRestartRequest(final Boolean supportsRestartRequest) {
+    this.supportsRestartRequest = supportsRestartRequest;
+  }
+  
+  /**
+   * The debug adapter supports 'exceptionOptions' on the setExceptionBreakpoints request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsExceptionOptions() {
+    return this.supportsExceptionOptions;
+  }
+  
+  /**
+   * The debug adapter supports 'exceptionOptions' on the setExceptionBreakpoints request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsExceptionOptions(final Boolean supportsExceptionOptions) {
+    this.supportsExceptionOptions = supportsExceptionOptions;
+  }
+  
+  /**
+   * The debug adapter supports a 'format' attribute on the stackTraceRequest, variablesRequest, and
+   * evaluateRequest.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsValueFormattingOptions() {
+    return this.supportsValueFormattingOptions;
+  }
+  
+  /**
+   * The debug adapter supports a 'format' attribute on the stackTraceRequest, variablesRequest, and
+   * evaluateRequest.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsValueFormattingOptions(final Boolean supportsValueFormattingOptions) {
+    this.supportsValueFormattingOptions = supportsValueFormattingOptions;
+  }
+  
+  /**
+   * The debug adapter supports the 'exceptionInfo' request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsExceptionInfoRequest() {
+    return this.supportsExceptionInfoRequest;
+  }
+  
+  /**
+   * The debug adapter supports the 'exceptionInfo' request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsExceptionInfoRequest(final Boolean supportsExceptionInfoRequest) {
+    this.supportsExceptionInfoRequest = supportsExceptionInfoRequest;
+  }
+  
+  /**
+   * The debug adapter supports the 'terminateDebuggee' attribute on the 'disconnect' request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportTerminateDebuggee() {
+    return this.supportTerminateDebuggee;
+  }
+  
+  /**
+   * The debug adapter supports the 'terminateDebuggee' attribute on the 'disconnect' request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportTerminateDebuggee(final Boolean supportTerminateDebuggee) {
+    this.supportTerminateDebuggee = supportTerminateDebuggee;
+  }
+  
+  /**
+   * The debug adapter supports the delayed loading of parts of the stack, which requires that both the 'startFrame'
+   * and 'levels' arguments and an optional 'totalFrames' result of the 'StackTrace' request are supported.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsDelayedStackTraceLoading() {
+    return this.supportsDelayedStackTraceLoading;
+  }
+  
+  /**
+   * The debug adapter supports the delayed loading of parts of the stack, which requires that both the 'startFrame'
+   * and 'levels' arguments and an optional 'totalFrames' result of the 'StackTrace' request are supported.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsDelayedStackTraceLoading(final Boolean supportsDelayedStackTraceLoading) {
+    this.supportsDelayedStackTraceLoading = supportsDelayedStackTraceLoading;
+  }
+  
+  /**
+   * The debug adapter supports the 'loadedSources' request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsLoadedSourcesRequest() {
+    return this.supportsLoadedSourcesRequest;
+  }
+  
+  /**
+   * The debug adapter supports the 'loadedSources' request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsLoadedSourcesRequest(final Boolean supportsLoadedSourcesRequest) {
+    this.supportsLoadedSourcesRequest = supportsLoadedSourcesRequest;
+  }
+  
+  /**
+   * The debug adapter supports logpoints by interpreting the 'logMessage' attribute of the SourceBreakpoint.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsLogPoints() {
+    return this.supportsLogPoints;
+  }
+  
+  /**
+   * The debug adapter supports logpoints by interpreting the 'logMessage' attribute of the SourceBreakpoint.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsLogPoints(final Boolean supportsLogPoints) {
+    this.supportsLogPoints = supportsLogPoints;
+  }
+  
+  /**
+   * The debug adapter supports the 'terminateThreads' request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsTerminateThreadsRequest() {
+    return this.supportsTerminateThreadsRequest;
+  }
+  
+  /**
+   * The debug adapter supports the 'terminateThreads' request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsTerminateThreadsRequest(final Boolean supportsTerminateThreadsRequest) {
+    this.supportsTerminateThreadsRequest = supportsTerminateThreadsRequest;
+  }
+  
+  /**
+   * The debug adapter supports the 'setExpression' request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsSetExpression() {
+    return this.supportsSetExpression;
+  }
+  
+  /**
+   * The debug adapter supports the 'setExpression' request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsSetExpression(final Boolean supportsSetExpression) {
+    this.supportsSetExpression = supportsSetExpression;
+  }
+  
+  /**
+   * The debug adapter supports the 'terminate' request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsTerminateRequest() {
+    return this.supportsTerminateRequest;
+  }
+  
+  /**
+   * The debug adapter supports the 'terminate' request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsTerminateRequest(final Boolean supportsTerminateRequest) {
+    this.supportsTerminateRequest = supportsTerminateRequest;
+  }
+  
+  /**
+   * The debug adapter supports data breakpoints.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsDataBreakpoints() {
+    return this.supportsDataBreakpoints;
+  }
+  
+  /**
+   * The debug adapter supports data breakpoints.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsDataBreakpoints(final Boolean supportsDataBreakpoints) {
+    this.supportsDataBreakpoints = supportsDataBreakpoints;
+  }
+  
+  /**
+   * The debug adapter supports the 'readMemory' request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsReadMemoryRequest() {
+    return this.supportsReadMemoryRequest;
+  }
+  
+  /**
+   * The debug adapter supports the 'readMemory' request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsReadMemoryRequest(final Boolean supportsReadMemoryRequest) {
+    this.supportsReadMemoryRequest = supportsReadMemoryRequest;
+  }
+  
+  /**
+   * The debug adapter supports the 'disassemble' request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsDisassembleRequest() {
+    return this.supportsDisassembleRequest;
+  }
+  
+  /**
+   * The debug adapter supports the 'disassemble' request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsDisassembleRequest(final Boolean supportsDisassembleRequest) {
+    this.supportsDisassembleRequest = supportsDisassembleRequest;
+  }
+  
+  /**
+   * The debug adapter supports the 'cancel' request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsCancelRequest() {
+    return this.supportsCancelRequest;
+  }
+  
+  /**
+   * The debug adapter supports the 'cancel' request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsCancelRequest(final Boolean supportsCancelRequest) {
+    this.supportsCancelRequest = supportsCancelRequest;
+  }
+  
+  /**
+   * The debug adapter supports the 'breakpointLocations' request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsBreakpointLocationsRequest() {
+    return this.supportsBreakpointLocationsRequest;
+  }
+  
+  /**
+   * The debug adapter supports the 'breakpointLocations' request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsBreakpointLocationsRequest(final Boolean supportsBreakpointLocationsRequest) {
+    this.supportsBreakpointLocationsRequest = supportsBreakpointLocationsRequest;
+  }
+  
+  /**
+   * The debug adapter supports the 'clipboard' context value in the 'evaluate' request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsClipboardContext() {
+    return this.supportsClipboardContext;
+  }
+  
+  /**
+   * The debug adapter supports the 'clipboard' context value in the 'evaluate' request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsClipboardContext(final Boolean supportsClipboardContext) {
+    this.supportsClipboardContext = supportsClipboardContext;
+  }
+  
+  /**
+   * The debug adapter supports stepping granularities (argument 'granularity') for the stepping requests.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsSteppingGranularity() {
+    return this.supportsSteppingGranularity;
+  }
+  
+  /**
+   * The debug adapter supports stepping granularities (argument 'granularity') for the stepping requests.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsSteppingGranularity(final Boolean supportsSteppingGranularity) {
+    this.supportsSteppingGranularity = supportsSteppingGranularity;
+  }
+  
+  /**
+   * The debug adapter supports adding breakpoints based on instruction references.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsInstructionBreakpoints() {
+    return this.supportsInstructionBreakpoints;
+  }
+  
+  /**
+   * The debug adapter supports adding breakpoints based on instruction references.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsInstructionBreakpoints(final Boolean supportsInstructionBreakpoints) {
+    this.supportsInstructionBreakpoints = supportsInstructionBreakpoints;
+  }
+  
+  /**
+   * The debug adapter supports 'filterOptions' as an argument on the 'setExceptionBreakpoints' request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsExceptionFilterOptions() {
+    return this.supportsExceptionFilterOptions;
+  }
+  
+  /**
+   * The debug adapter supports 'filterOptions' as an argument on the 'setExceptionBreakpoints' request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsExceptionFilterOptions(final Boolean supportsExceptionFilterOptions) {
+    this.supportsExceptionFilterOptions = supportsExceptionFilterOptions;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("supportsConfigurationDoneRequest", this.supportsConfigurationDoneRequest);
+    b.add("supportsFunctionBreakpoints", this.supportsFunctionBreakpoints);
+    b.add("supportsConditionalBreakpoints", this.supportsConditionalBreakpoints);
+    b.add("supportsHitConditionalBreakpoints", this.supportsHitConditionalBreakpoints);
+    b.add("supportsEvaluateForHovers", this.supportsEvaluateForHovers);
+    b.add("exceptionBreakpointFilters", this.exceptionBreakpointFilters);
+    b.add("supportsStepBack", this.supportsStepBack);
+    b.add("supportsSetVariable", this.supportsSetVariable);
+    b.add("supportsRestartFrame", this.supportsRestartFrame);
+    b.add("supportsGotoTargetsRequest", this.supportsGotoTargetsRequest);
+    b.add("supportsStepInTargetsRequest", this.supportsStepInTargetsRequest);
+    b.add("supportsCompletionsRequest", this.supportsCompletionsRequest);
+    b.add("completionTriggerCharacters", this.completionTriggerCharacters);
+    b.add("supportsModulesRequest", this.supportsModulesRequest);
+    b.add("additionalModuleColumns", this.additionalModuleColumns);
+    b.add("supportedChecksumAlgorithms", this.supportedChecksumAlgorithms);
+    b.add("supportsRestartRequest", this.supportsRestartRequest);
+    b.add("supportsExceptionOptions", this.supportsExceptionOptions);
+    b.add("supportsValueFormattingOptions", this.supportsValueFormattingOptions);
+    b.add("supportsExceptionInfoRequest", this.supportsExceptionInfoRequest);
+    b.add("supportTerminateDebuggee", this.supportTerminateDebuggee);
+    b.add("supportsDelayedStackTraceLoading", this.supportsDelayedStackTraceLoading);
+    b.add("supportsLoadedSourcesRequest", this.supportsLoadedSourcesRequest);
+    b.add("supportsLogPoints", this.supportsLogPoints);
+    b.add("supportsTerminateThreadsRequest", this.supportsTerminateThreadsRequest);
+    b.add("supportsSetExpression", this.supportsSetExpression);
+    b.add("supportsTerminateRequest", this.supportsTerminateRequest);
+    b.add("supportsDataBreakpoints", this.supportsDataBreakpoints);
+    b.add("supportsReadMemoryRequest", this.supportsReadMemoryRequest);
+    b.add("supportsDisassembleRequest", this.supportsDisassembleRequest);
+    b.add("supportsCancelRequest", this.supportsCancelRequest);
+    b.add("supportsBreakpointLocationsRequest", this.supportsBreakpointLocationsRequest);
+    b.add("supportsClipboardContext", this.supportsClipboardContext);
+    b.add("supportsSteppingGranularity", this.supportsSteppingGranularity);
+    b.add("supportsInstructionBreakpoints", this.supportsInstructionBreakpoints);
+    b.add("supportsExceptionFilterOptions", this.supportsExceptionFilterOptions);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    Capabilities other = (Capabilities) obj;
+    if (this.supportsConfigurationDoneRequest == null) {
+      if (other.supportsConfigurationDoneRequest != null)
+        return false;
+    } else if (!this.supportsConfigurationDoneRequest.equals(other.supportsConfigurationDoneRequest))
+      return false;
+    if (this.supportsFunctionBreakpoints == null) {
+      if (other.supportsFunctionBreakpoints != null)
+        return false;
+    } else if (!this.supportsFunctionBreakpoints.equals(other.supportsFunctionBreakpoints))
+      return false;
+    if (this.supportsConditionalBreakpoints == null) {
+      if (other.supportsConditionalBreakpoints != null)
+        return false;
+    } else if (!this.supportsConditionalBreakpoints.equals(other.supportsConditionalBreakpoints))
+      return false;
+    if (this.supportsHitConditionalBreakpoints == null) {
+      if (other.supportsHitConditionalBreakpoints != null)
+        return false;
+    } else if (!this.supportsHitConditionalBreakpoints.equals(other.supportsHitConditionalBreakpoints))
+      return false;
+    if (this.supportsEvaluateForHovers == null) {
+      if (other.supportsEvaluateForHovers != null)
+        return false;
+    } else if (!this.supportsEvaluateForHovers.equals(other.supportsEvaluateForHovers))
+      return false;
+    if (this.exceptionBreakpointFilters == null) {
+      if (other.exceptionBreakpointFilters != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.exceptionBreakpointFilters, other.exceptionBreakpointFilters))
+      return false;
+    if (this.supportsStepBack == null) {
+      if (other.supportsStepBack != null)
+        return false;
+    } else if (!this.supportsStepBack.equals(other.supportsStepBack))
+      return false;
+    if (this.supportsSetVariable == null) {
+      if (other.supportsSetVariable != null)
+        return false;
+    } else if (!this.supportsSetVariable.equals(other.supportsSetVariable))
+      return false;
+    if (this.supportsRestartFrame == null) {
+      if (other.supportsRestartFrame != null)
+        return false;
+    } else if (!this.supportsRestartFrame.equals(other.supportsRestartFrame))
+      return false;
+    if (this.supportsGotoTargetsRequest == null) {
+      if (other.supportsGotoTargetsRequest != null)
+        return false;
+    } else if (!this.supportsGotoTargetsRequest.equals(other.supportsGotoTargetsRequest))
+      return false;
+    if (this.supportsStepInTargetsRequest == null) {
+      if (other.supportsStepInTargetsRequest != null)
+        return false;
+    } else if (!this.supportsStepInTargetsRequest.equals(other.supportsStepInTargetsRequest))
+      return false;
+    if (this.supportsCompletionsRequest == null) {
+      if (other.supportsCompletionsRequest != null)
+        return false;
+    } else if (!this.supportsCompletionsRequest.equals(other.supportsCompletionsRequest))
+      return false;
+    if (this.completionTriggerCharacters == null) {
+      if (other.completionTriggerCharacters != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.completionTriggerCharacters, other.completionTriggerCharacters))
+      return false;
+    if (this.supportsModulesRequest == null) {
+      if (other.supportsModulesRequest != null)
+        return false;
+    } else if (!this.supportsModulesRequest.equals(other.supportsModulesRequest))
+      return false;
+    if (this.additionalModuleColumns == null) {
+      if (other.additionalModuleColumns != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.additionalModuleColumns, other.additionalModuleColumns))
+      return false;
+    if (this.supportedChecksumAlgorithms == null) {
+      if (other.supportedChecksumAlgorithms != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.supportedChecksumAlgorithms, other.supportedChecksumAlgorithms))
+      return false;
+    if (this.supportsRestartRequest == null) {
+      if (other.supportsRestartRequest != null)
+        return false;
+    } else if (!this.supportsRestartRequest.equals(other.supportsRestartRequest))
+      return false;
+    if (this.supportsExceptionOptions == null) {
+      if (other.supportsExceptionOptions != null)
+        return false;
+    } else if (!this.supportsExceptionOptions.equals(other.supportsExceptionOptions))
+      return false;
+    if (this.supportsValueFormattingOptions == null) {
+      if (other.supportsValueFormattingOptions != null)
+        return false;
+    } else if (!this.supportsValueFormattingOptions.equals(other.supportsValueFormattingOptions))
+      return false;
+    if (this.supportsExceptionInfoRequest == null) {
+      if (other.supportsExceptionInfoRequest != null)
+        return false;
+    } else if (!this.supportsExceptionInfoRequest.equals(other.supportsExceptionInfoRequest))
+      return false;
+    if (this.supportTerminateDebuggee == null) {
+      if (other.supportTerminateDebuggee != null)
+        return false;
+    } else if (!this.supportTerminateDebuggee.equals(other.supportTerminateDebuggee))
+      return false;
+    if (this.supportsDelayedStackTraceLoading == null) {
+      if (other.supportsDelayedStackTraceLoading != null)
+        return false;
+    } else if (!this.supportsDelayedStackTraceLoading.equals(other.supportsDelayedStackTraceLoading))
+      return false;
+    if (this.supportsLoadedSourcesRequest == null) {
+      if (other.supportsLoadedSourcesRequest != null)
+        return false;
+    } else if (!this.supportsLoadedSourcesRequest.equals(other.supportsLoadedSourcesRequest))
+      return false;
+    if (this.supportsLogPoints == null) {
+      if (other.supportsLogPoints != null)
+        return false;
+    } else if (!this.supportsLogPoints.equals(other.supportsLogPoints))
+      return false;
+    if (this.supportsTerminateThreadsRequest == null) {
+      if (other.supportsTerminateThreadsRequest != null)
+        return false;
+    } else if (!this.supportsTerminateThreadsRequest.equals(other.supportsTerminateThreadsRequest))
+      return false;
+    if (this.supportsSetExpression == null) {
+      if (other.supportsSetExpression != null)
+        return false;
+    } else if (!this.supportsSetExpression.equals(other.supportsSetExpression))
+      return false;
+    if (this.supportsTerminateRequest == null) {
+      if (other.supportsTerminateRequest != null)
+        return false;
+    } else if (!this.supportsTerminateRequest.equals(other.supportsTerminateRequest))
+      return false;
+    if (this.supportsDataBreakpoints == null) {
+      if (other.supportsDataBreakpoints != null)
+        return false;
+    } else if (!this.supportsDataBreakpoints.equals(other.supportsDataBreakpoints))
+      return false;
+    if (this.supportsReadMemoryRequest == null) {
+      if (other.supportsReadMemoryRequest != null)
+        return false;
+    } else if (!this.supportsReadMemoryRequest.equals(other.supportsReadMemoryRequest))
+      return false;
+    if (this.supportsDisassembleRequest == null) {
+      if (other.supportsDisassembleRequest != null)
+        return false;
+    } else if (!this.supportsDisassembleRequest.equals(other.supportsDisassembleRequest))
+      return false;
+    if (this.supportsCancelRequest == null) {
+      if (other.supportsCancelRequest != null)
+        return false;
+    } else if (!this.supportsCancelRequest.equals(other.supportsCancelRequest))
+      return false;
+    if (this.supportsBreakpointLocationsRequest == null) {
+      if (other.supportsBreakpointLocationsRequest != null)
+        return false;
+    } else if (!this.supportsBreakpointLocationsRequest.equals(other.supportsBreakpointLocationsRequest))
+      return false;
+    if (this.supportsClipboardContext == null) {
+      if (other.supportsClipboardContext != null)
+        return false;
+    } else if (!this.supportsClipboardContext.equals(other.supportsClipboardContext))
+      return false;
+    if (this.supportsSteppingGranularity == null) {
+      if (other.supportsSteppingGranularity != null)
+        return false;
+    } else if (!this.supportsSteppingGranularity.equals(other.supportsSteppingGranularity))
+      return false;
+    if (this.supportsInstructionBreakpoints == null) {
+      if (other.supportsInstructionBreakpoints != null)
+        return false;
+    } else if (!this.supportsInstructionBreakpoints.equals(other.supportsInstructionBreakpoints))
+      return false;
+    if (this.supportsExceptionFilterOptions == null) {
+      if (other.supportsExceptionFilterOptions != null)
+        return false;
+    } else if (!this.supportsExceptionFilterOptions.equals(other.supportsExceptionFilterOptions))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.supportsConfigurationDoneRequest== null) ? 0 : this.supportsConfigurationDoneRequest.hashCode());
+    result = prime * result + ((this.supportsFunctionBreakpoints== null) ? 0 : this.supportsFunctionBreakpoints.hashCode());
+    result = prime * result + ((this.supportsConditionalBreakpoints== null) ? 0 : this.supportsConditionalBreakpoints.hashCode());
+    result = prime * result + ((this.supportsHitConditionalBreakpoints== null) ? 0 : this.supportsHitConditionalBreakpoints.hashCode());
+    result = prime * result + ((this.supportsEvaluateForHovers== null) ? 0 : this.supportsEvaluateForHovers.hashCode());
+    result = prime * result + ((this.exceptionBreakpointFilters== null) ? 0 : Arrays.deepHashCode(this.exceptionBreakpointFilters));
+    result = prime * result + ((this.supportsStepBack== null) ? 0 : this.supportsStepBack.hashCode());
+    result = prime * result + ((this.supportsSetVariable== null) ? 0 : this.supportsSetVariable.hashCode());
+    result = prime * result + ((this.supportsRestartFrame== null) ? 0 : this.supportsRestartFrame.hashCode());
+    result = prime * result + ((this.supportsGotoTargetsRequest== null) ? 0 : this.supportsGotoTargetsRequest.hashCode());
+    result = prime * result + ((this.supportsStepInTargetsRequest== null) ? 0 : this.supportsStepInTargetsRequest.hashCode());
+    result = prime * result + ((this.supportsCompletionsRequest== null) ? 0 : this.supportsCompletionsRequest.hashCode());
+    result = prime * result + ((this.completionTriggerCharacters== null) ? 0 : Arrays.deepHashCode(this.completionTriggerCharacters));
+    result = prime * result + ((this.supportsModulesRequest== null) ? 0 : this.supportsModulesRequest.hashCode());
+    result = prime * result + ((this.additionalModuleColumns== null) ? 0 : Arrays.deepHashCode(this.additionalModuleColumns));
+    result = prime * result + ((this.supportedChecksumAlgorithms== null) ? 0 : Arrays.deepHashCode(this.supportedChecksumAlgorithms));
+    result = prime * result + ((this.supportsRestartRequest== null) ? 0 : this.supportsRestartRequest.hashCode());
+    result = prime * result + ((this.supportsExceptionOptions== null) ? 0 : this.supportsExceptionOptions.hashCode());
+    result = prime * result + ((this.supportsValueFormattingOptions== null) ? 0 : this.supportsValueFormattingOptions.hashCode());
+    result = prime * result + ((this.supportsExceptionInfoRequest== null) ? 0 : this.supportsExceptionInfoRequest.hashCode());
+    result = prime * result + ((this.supportTerminateDebuggee== null) ? 0 : this.supportTerminateDebuggee.hashCode());
+    result = prime * result + ((this.supportsDelayedStackTraceLoading== null) ? 0 : this.supportsDelayedStackTraceLoading.hashCode());
+    result = prime * result + ((this.supportsLoadedSourcesRequest== null) ? 0 : this.supportsLoadedSourcesRequest.hashCode());
+    result = prime * result + ((this.supportsLogPoints== null) ? 0 : this.supportsLogPoints.hashCode());
+    result = prime * result + ((this.supportsTerminateThreadsRequest== null) ? 0 : this.supportsTerminateThreadsRequest.hashCode());
+    result = prime * result + ((this.supportsSetExpression== null) ? 0 : this.supportsSetExpression.hashCode());
+    result = prime * result + ((this.supportsTerminateRequest== null) ? 0 : this.supportsTerminateRequest.hashCode());
+    result = prime * result + ((this.supportsDataBreakpoints== null) ? 0 : this.supportsDataBreakpoints.hashCode());
+    result = prime * result + ((this.supportsReadMemoryRequest== null) ? 0 : this.supportsReadMemoryRequest.hashCode());
+    result = prime * result + ((this.supportsDisassembleRequest== null) ? 0 : this.supportsDisassembleRequest.hashCode());
+    result = prime * result + ((this.supportsCancelRequest== null) ? 0 : this.supportsCancelRequest.hashCode());
+    result = prime * result + ((this.supportsBreakpointLocationsRequest== null) ? 0 : this.supportsBreakpointLocationsRequest.hashCode());
+    result = prime * result + ((this.supportsClipboardContext== null) ? 0 : this.supportsClipboardContext.hashCode());
+    result = prime * result + ((this.supportsSteppingGranularity== null) ? 0 : this.supportsSteppingGranularity.hashCode());
+    result = prime * result + ((this.supportsInstructionBreakpoints== null) ? 0 : this.supportsInstructionBreakpoints.hashCode());
+    return prime * result + ((this.supportsExceptionFilterOptions== null) ? 0 : this.supportsExceptionFilterOptions.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/CapabilitiesEventArguments.java b/java/org/eclipse/lsp4j/debug/CapabilitiesEventArguments.java
new file mode 100644
index 0000000..a34eaba
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/CapabilitiesEventArguments.java
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.Capabilities;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The event indicates that one or more capabilities have changed.
+ * <p>
+ * Since the capabilities are dependent on the frontend and its UI, it might not be possible to change that at
+ * random times (or too late).
+ * <p>
+ * Consequently this event has a hint characteristic: a frontend can only be expected to make a 'best effort' in
+ * honouring individual capabilities but there are no guarantees.
+ * <p>
+ * Only changed capabilities need to be included, all other capabilities keep their values.
+ */
+@SuppressWarnings("all")
+public class CapabilitiesEventArguments {
+  /**
+   * The set of updated capabilities.
+   */
+  @NonNull
+  private Capabilities capabilities;
+  
+  /**
+   * The set of updated capabilities.
+   */
+  @Pure
+  @NonNull
+  public Capabilities getCapabilities() {
+    return this.capabilities;
+  }
+  
+  /**
+   * The set of updated capabilities.
+   */
+  public void setCapabilities(@NonNull final Capabilities capabilities) {
+    this.capabilities = Preconditions.checkNotNull(capabilities, "capabilities");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("capabilities", this.capabilities);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CapabilitiesEventArguments other = (CapabilitiesEventArguments) obj;
+    if (this.capabilities == null) {
+      if (other.capabilities != null)
+        return false;
+    } else if (!this.capabilities.equals(other.capabilities))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.capabilities== null) ? 0 : this.capabilities.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/Checksum.java b/java/org/eclipse/lsp4j/debug/Checksum.java
new file mode 100644
index 0000000..06e1e06
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/Checksum.java
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.ChecksumAlgorithm;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The checksum of an item calculated by the specified algorithm.
+ */
+@SuppressWarnings("all")
+public class Checksum {
+  /**
+   * The algorithm used to calculate this checksum.
+   */
+  @NonNull
+  private ChecksumAlgorithm algorithm;
+  
+  /**
+   * Value of the checksum.
+   */
+  @NonNull
+  private String checksum;
+  
+  /**
+   * The algorithm used to calculate this checksum.
+   */
+  @Pure
+  @NonNull
+  public ChecksumAlgorithm getAlgorithm() {
+    return this.algorithm;
+  }
+  
+  /**
+   * The algorithm used to calculate this checksum.
+   */
+  public void setAlgorithm(@NonNull final ChecksumAlgorithm algorithm) {
+    this.algorithm = Preconditions.checkNotNull(algorithm, "algorithm");
+  }
+  
+  /**
+   * Value of the checksum.
+   */
+  @Pure
+  @NonNull
+  public String getChecksum() {
+    return this.checksum;
+  }
+  
+  /**
+   * Value of the checksum.
+   */
+  public void setChecksum(@NonNull final String checksum) {
+    this.checksum = Preconditions.checkNotNull(checksum, "checksum");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("algorithm", this.algorithm);
+    b.add("checksum", this.checksum);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    Checksum other = (Checksum) obj;
+    if (this.algorithm == null) {
+      if (other.algorithm != null)
+        return false;
+    } else if (!this.algorithm.equals(other.algorithm))
+      return false;
+    if (this.checksum == null) {
+      if (other.checksum != null)
+        return false;
+    } else if (!this.checksum.equals(other.checksum))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.algorithm== null) ? 0 : this.algorithm.hashCode());
+    return prime * result + ((this.checksum== null) ? 0 : this.checksum.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ChecksumAlgorithm.java b/java/org/eclipse/lsp4j/debug/ChecksumAlgorithm.java
new file mode 100644
index 0000000..c579542
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ChecksumAlgorithm.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * Names of checksum algorithms that may be supported by a debug adapter.
+ */
+@SuppressWarnings("all")
+public enum ChecksumAlgorithm {
+  @SerializedName("MD5")
+  MD5,
+  
+  @SerializedName("SHA1")
+  SHA1,
+  
+  @SerializedName("SHA256")
+  SHA256,
+  
+  TIMESTAMP;
+}
diff --git a/java/org/eclipse/lsp4j/debug/ColumnDescriptor.java b/java/org/eclipse/lsp4j/debug/ColumnDescriptor.java
new file mode 100644
index 0000000..350b118
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ColumnDescriptor.java
@@ -0,0 +1,212 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.ColumnDescriptorType;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A ColumnDescriptor specifies what module attribute to show in a column of the ModulesView, how to format it,
+ * <p>
+ * and what the column's label should be.
+ * <p>
+ * It is only used if the underlying UI actually supports this level of customization.
+ */
+@SuppressWarnings("all")
+public class ColumnDescriptor {
+  /**
+   * Name of the attribute rendered in this column.
+   */
+  @NonNull
+  private String attributeName;
+  
+  /**
+   * Header UI label of column.
+   */
+  @NonNull
+  private String label;
+  
+  /**
+   * Format to use for the rendered values in this column. TBD how the format strings looks like.
+   * <p>
+   * This is an optional property.
+   */
+  private String format;
+  
+  /**
+   * Datatype of values in this column.  Defaults to 'string' if not specified.
+   * <p>
+   * This is an optional property.
+   */
+  private ColumnDescriptorType type;
+  
+  /**
+   * Width of this column in characters (hint only).
+   * <p>
+   * This is an optional property.
+   */
+  private Integer width;
+  
+  /**
+   * Name of the attribute rendered in this column.
+   */
+  @Pure
+  @NonNull
+  public String getAttributeName() {
+    return this.attributeName;
+  }
+  
+  /**
+   * Name of the attribute rendered in this column.
+   */
+  public void setAttributeName(@NonNull final String attributeName) {
+    this.attributeName = Preconditions.checkNotNull(attributeName, "attributeName");
+  }
+  
+  /**
+   * Header UI label of column.
+   */
+  @Pure
+  @NonNull
+  public String getLabel() {
+    return this.label;
+  }
+  
+  /**
+   * Header UI label of column.
+   */
+  public void setLabel(@NonNull final String label) {
+    this.label = Preconditions.checkNotNull(label, "label");
+  }
+  
+  /**
+   * Format to use for the rendered values in this column. TBD how the format strings looks like.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getFormat() {
+    return this.format;
+  }
+  
+  /**
+   * Format to use for the rendered values in this column. TBD how the format strings looks like.
+   * <p>
+   * This is an optional property.
+   */
+  public void setFormat(final String format) {
+    this.format = format;
+  }
+  
+  /**
+   * Datatype of values in this column.  Defaults to 'string' if not specified.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public ColumnDescriptorType getType() {
+    return this.type;
+  }
+  
+  /**
+   * Datatype of values in this column.  Defaults to 'string' if not specified.
+   * <p>
+   * This is an optional property.
+   */
+  public void setType(final ColumnDescriptorType type) {
+    this.type = type;
+  }
+  
+  /**
+   * Width of this column in characters (hint only).
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getWidth() {
+    return this.width;
+  }
+  
+  /**
+   * Width of this column in characters (hint only).
+   * <p>
+   * This is an optional property.
+   */
+  public void setWidth(final Integer width) {
+    this.width = width;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("attributeName", this.attributeName);
+    b.add("label", this.label);
+    b.add("format", this.format);
+    b.add("type", this.type);
+    b.add("width", this.width);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ColumnDescriptor other = (ColumnDescriptor) obj;
+    if (this.attributeName == null) {
+      if (other.attributeName != null)
+        return false;
+    } else if (!this.attributeName.equals(other.attributeName))
+      return false;
+    if (this.label == null) {
+      if (other.label != null)
+        return false;
+    } else if (!this.label.equals(other.label))
+      return false;
+    if (this.format == null) {
+      if (other.format != null)
+        return false;
+    } else if (!this.format.equals(other.format))
+      return false;
+    if (this.type == null) {
+      if (other.type != null)
+        return false;
+    } else if (!this.type.equals(other.type))
+      return false;
+    if (this.width == null) {
+      if (other.width != null)
+        return false;
+    } else if (!this.width.equals(other.width))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.attributeName== null) ? 0 : this.attributeName.hashCode());
+    result = prime * result + ((this.label== null) ? 0 : this.label.hashCode());
+    result = prime * result + ((this.format== null) ? 0 : this.format.hashCode());
+    result = prime * result + ((this.type== null) ? 0 : this.type.hashCode());
+    return prime * result + ((this.width== null) ? 0 : this.width.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ColumnDescriptorType.java b/java/org/eclipse/lsp4j/debug/ColumnDescriptorType.java
new file mode 100644
index 0000000..ab83b85
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ColumnDescriptorType.java
@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * Datatype of values in this column.  Defaults to 'string' if not specified.
+ */
+@SuppressWarnings("all")
+public enum ColumnDescriptorType {
+  STRING,
+  
+  NUMBER,
+  
+  BOOLEAN,
+  
+  @SerializedName("unixTimestampUTC")
+  UNIX_TIMESTAMP_UTC;
+}
diff --git a/java/org/eclipse/lsp4j/debug/CompletionItem.java b/java/org/eclipse/lsp4j/debug/CompletionItem.java
new file mode 100644
index 0000000..2fde17f
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/CompletionItem.java
@@ -0,0 +1,353 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.CompletionItemType;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * CompletionItems are the suggestions returned from the CompletionsRequest.
+ */
+@SuppressWarnings("all")
+public class CompletionItem {
+  /**
+   * The label of this completion item. By default this is also the text that is inserted when selecting this
+   * completion.
+   */
+  @NonNull
+  private String label;
+  
+  /**
+   * If text is not falsy then it is inserted instead of the label.
+   * <p>
+   * This is an optional property.
+   */
+  private String text;
+  
+  /**
+   * A string that should be used when comparing this item with other items. When `falsy` the label is used.
+   * <p>
+   * This is an optional property.
+   */
+  private String sortText;
+  
+  /**
+   * The item's type. Typically the client uses this information to render the item in the UI with an icon.
+   * <p>
+   * This is an optional property.
+   */
+  private CompletionItemType type;
+  
+  /**
+   * This value determines the location (in the CompletionsRequest's 'text' attribute) where the completion text is
+   * added.
+   * <p>
+   * If missing the text is added at the location specified by the CompletionsRequest's 'column' attribute.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer start;
+  
+  /**
+   * This value determines how many characters are overwritten by the completion text.
+   * <p>
+   * If missing the value 0 is assumed which results in the completion text being inserted.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer length;
+  
+  /**
+   * Determines the start of the new selection after the text has been inserted (or replaced).
+   * <p>
+   * The start position must in the range 0 and length of the completion text.
+   * <p>
+   * If omitted the selection starts at the end of the completion text.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer selectionStart;
+  
+  /**
+   * Determines the length of the new selection after the text has been inserted (or replaced).
+   * <p>
+   * The selection can not extend beyond the bounds of the completion text.
+   * <p>
+   * If omitted the length is assumed to be 0.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer selectionLength;
+  
+  /**
+   * The label of this completion item. By default this is also the text that is inserted when selecting this
+   * completion.
+   */
+  @Pure
+  @NonNull
+  public String getLabel() {
+    return this.label;
+  }
+  
+  /**
+   * The label of this completion item. By default this is also the text that is inserted when selecting this
+   * completion.
+   */
+  public void setLabel(@NonNull final String label) {
+    this.label = Preconditions.checkNotNull(label, "label");
+  }
+  
+  /**
+   * If text is not falsy then it is inserted instead of the label.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getText() {
+    return this.text;
+  }
+  
+  /**
+   * If text is not falsy then it is inserted instead of the label.
+   * <p>
+   * This is an optional property.
+   */
+  public void setText(final String text) {
+    this.text = text;
+  }
+  
+  /**
+   * A string that should be used when comparing this item with other items. When `falsy` the label is used.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getSortText() {
+    return this.sortText;
+  }
+  
+  /**
+   * A string that should be used when comparing this item with other items. When `falsy` the label is used.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSortText(final String sortText) {
+    this.sortText = sortText;
+  }
+  
+  /**
+   * The item's type. Typically the client uses this information to render the item in the UI with an icon.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public CompletionItemType getType() {
+    return this.type;
+  }
+  
+  /**
+   * The item's type. Typically the client uses this information to render the item in the UI with an icon.
+   * <p>
+   * This is an optional property.
+   */
+  public void setType(final CompletionItemType type) {
+    this.type = type;
+  }
+  
+  /**
+   * This value determines the location (in the CompletionsRequest's 'text' attribute) where the completion text is
+   * added.
+   * <p>
+   * If missing the text is added at the location specified by the CompletionsRequest's 'column' attribute.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getStart() {
+    return this.start;
+  }
+  
+  /**
+   * This value determines the location (in the CompletionsRequest's 'text' attribute) where the completion text is
+   * added.
+   * <p>
+   * If missing the text is added at the location specified by the CompletionsRequest's 'column' attribute.
+   * <p>
+   * This is an optional property.
+   */
+  public void setStart(final Integer start) {
+    this.start = start;
+  }
+  
+  /**
+   * This value determines how many characters are overwritten by the completion text.
+   * <p>
+   * If missing the value 0 is assumed which results in the completion text being inserted.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getLength() {
+    return this.length;
+  }
+  
+  /**
+   * This value determines how many characters are overwritten by the completion text.
+   * <p>
+   * If missing the value 0 is assumed which results in the completion text being inserted.
+   * <p>
+   * This is an optional property.
+   */
+  public void setLength(final Integer length) {
+    this.length = length;
+  }
+  
+  /**
+   * Determines the start of the new selection after the text has been inserted (or replaced).
+   * <p>
+   * The start position must in the range 0 and length of the completion text.
+   * <p>
+   * If omitted the selection starts at the end of the completion text.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getSelectionStart() {
+    return this.selectionStart;
+  }
+  
+  /**
+   * Determines the start of the new selection after the text has been inserted (or replaced).
+   * <p>
+   * The start position must in the range 0 and length of the completion text.
+   * <p>
+   * If omitted the selection starts at the end of the completion text.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSelectionStart(final Integer selectionStart) {
+    this.selectionStart = selectionStart;
+  }
+  
+  /**
+   * Determines the length of the new selection after the text has been inserted (or replaced).
+   * <p>
+   * The selection can not extend beyond the bounds of the completion text.
+   * <p>
+   * If omitted the length is assumed to be 0.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getSelectionLength() {
+    return this.selectionLength;
+  }
+  
+  /**
+   * Determines the length of the new selection after the text has been inserted (or replaced).
+   * <p>
+   * The selection can not extend beyond the bounds of the completion text.
+   * <p>
+   * If omitted the length is assumed to be 0.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSelectionLength(final Integer selectionLength) {
+    this.selectionLength = selectionLength;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("label", this.label);
+    b.add("text", this.text);
+    b.add("sortText", this.sortText);
+    b.add("type", this.type);
+    b.add("start", this.start);
+    b.add("length", this.length);
+    b.add("selectionStart", this.selectionStart);
+    b.add("selectionLength", this.selectionLength);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CompletionItem other = (CompletionItem) obj;
+    if (this.label == null) {
+      if (other.label != null)
+        return false;
+    } else if (!this.label.equals(other.label))
+      return false;
+    if (this.text == null) {
+      if (other.text != null)
+        return false;
+    } else if (!this.text.equals(other.text))
+      return false;
+    if (this.sortText == null) {
+      if (other.sortText != null)
+        return false;
+    } else if (!this.sortText.equals(other.sortText))
+      return false;
+    if (this.type == null) {
+      if (other.type != null)
+        return false;
+    } else if (!this.type.equals(other.type))
+      return false;
+    if (this.start == null) {
+      if (other.start != null)
+        return false;
+    } else if (!this.start.equals(other.start))
+      return false;
+    if (this.length == null) {
+      if (other.length != null)
+        return false;
+    } else if (!this.length.equals(other.length))
+      return false;
+    if (this.selectionStart == null) {
+      if (other.selectionStart != null)
+        return false;
+    } else if (!this.selectionStart.equals(other.selectionStart))
+      return false;
+    if (this.selectionLength == null) {
+      if (other.selectionLength != null)
+        return false;
+    } else if (!this.selectionLength.equals(other.selectionLength))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.label== null) ? 0 : this.label.hashCode());
+    result = prime * result + ((this.text== null) ? 0 : this.text.hashCode());
+    result = prime * result + ((this.sortText== null) ? 0 : this.sortText.hashCode());
+    result = prime * result + ((this.type== null) ? 0 : this.type.hashCode());
+    result = prime * result + ((this.start== null) ? 0 : this.start.hashCode());
+    result = prime * result + ((this.length== null) ? 0 : this.length.hashCode());
+    result = prime * result + ((this.selectionStart== null) ? 0 : this.selectionStart.hashCode());
+    return prime * result + ((this.selectionLength== null) ? 0 : this.selectionLength.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/CompletionItemType.java b/java/org/eclipse/lsp4j/debug/CompletionItemType.java
new file mode 100644
index 0000000..9b47e79
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/CompletionItemType.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+/**
+ * Some predefined types for the CompletionItem. Please note that not all clients have specific icons for all of
+ * them.
+ */
+@SuppressWarnings("all")
+public enum CompletionItemType {
+  METHOD,
+  
+  FUNCTION,
+  
+  CONSTRUCTOR,
+  
+  FIELD,
+  
+  VARIABLE,
+  
+  CLASS,
+  
+  INTERFACE,
+  
+  MODULE,
+  
+  PROPERTY,
+  
+  UNIT,
+  
+  VALUE,
+  
+  ENUM,
+  
+  KEYWORD,
+  
+  SNIPPET,
+  
+  TEXT,
+  
+  COLOR,
+  
+  FILE,
+  
+  REFERENCE,
+  
+  CUSTOMCOLOR;
+}
diff --git a/java/org/eclipse/lsp4j/debug/CompletionsArguments.java b/java/org/eclipse/lsp4j/debug/CompletionsArguments.java
new file mode 100644
index 0000000..abb9e5d
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/CompletionsArguments.java
@@ -0,0 +1,178 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'completions' request.
+ */
+@SuppressWarnings("all")
+public class CompletionsArguments {
+  /**
+   * Returns completions in the scope of this stack frame. If not specified, the completions are returned for the
+   * global scope.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer frameId;
+  
+  /**
+   * One or more source lines. Typically this is the text a user has typed into the debug console before he asked
+   * for completion.
+   */
+  @NonNull
+  private String text;
+  
+  /**
+   * The character position for which to determine the completion proposals.
+   */
+  private int column;
+  
+  /**
+   * An optional line for which to determine the completion proposals. If missing the first line of the text is
+   * assumed.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer line;
+  
+  /**
+   * Returns completions in the scope of this stack frame. If not specified, the completions are returned for the
+   * global scope.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getFrameId() {
+    return this.frameId;
+  }
+  
+  /**
+   * Returns completions in the scope of this stack frame. If not specified, the completions are returned for the
+   * global scope.
+   * <p>
+   * This is an optional property.
+   */
+  public void setFrameId(final Integer frameId) {
+    this.frameId = frameId;
+  }
+  
+  /**
+   * One or more source lines. Typically this is the text a user has typed into the debug console before he asked
+   * for completion.
+   */
+  @Pure
+  @NonNull
+  public String getText() {
+    return this.text;
+  }
+  
+  /**
+   * One or more source lines. Typically this is the text a user has typed into the debug console before he asked
+   * for completion.
+   */
+  public void setText(@NonNull final String text) {
+    this.text = Preconditions.checkNotNull(text, "text");
+  }
+  
+  /**
+   * The character position for which to determine the completion proposals.
+   */
+  @Pure
+  public int getColumn() {
+    return this.column;
+  }
+  
+  /**
+   * The character position for which to determine the completion proposals.
+   */
+  public void setColumn(final int column) {
+    this.column = column;
+  }
+  
+  /**
+   * An optional line for which to determine the completion proposals. If missing the first line of the text is
+   * assumed.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getLine() {
+    return this.line;
+  }
+  
+  /**
+   * An optional line for which to determine the completion proposals. If missing the first line of the text is
+   * assumed.
+   * <p>
+   * This is an optional property.
+   */
+  public void setLine(final Integer line) {
+    this.line = line;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("frameId", this.frameId);
+    b.add("text", this.text);
+    b.add("column", this.column);
+    b.add("line", this.line);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CompletionsArguments other = (CompletionsArguments) obj;
+    if (this.frameId == null) {
+      if (other.frameId != null)
+        return false;
+    } else if (!this.frameId.equals(other.frameId))
+      return false;
+    if (this.text == null) {
+      if (other.text != null)
+        return false;
+    } else if (!this.text.equals(other.text))
+      return false;
+    if (other.column != this.column)
+      return false;
+    if (this.line == null) {
+      if (other.line != null)
+        return false;
+    } else if (!this.line.equals(other.line))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.frameId== null) ? 0 : this.frameId.hashCode());
+    result = prime * result + ((this.text== null) ? 0 : this.text.hashCode());
+    result = prime * result + this.column;
+    return prime * result + ((this.line== null) ? 0 : this.line.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/CompletionsResponse.java b/java/org/eclipse/lsp4j/debug/CompletionsResponse.java
new file mode 100644
index 0000000..f8e7fcd
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/CompletionsResponse.java
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.lsp4j.debug.CompletionItem;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Response to 'completions' request.
+ */
+@SuppressWarnings("all")
+public class CompletionsResponse {
+  /**
+   * The possible completions for .
+   */
+  @NonNull
+  private CompletionItem[] targets;
+  
+  /**
+   * The possible completions for .
+   */
+  @Pure
+  @NonNull
+  public CompletionItem[] getTargets() {
+    return this.targets;
+  }
+  
+  /**
+   * The possible completions for .
+   */
+  public void setTargets(@NonNull final CompletionItem[] targets) {
+    this.targets = Preconditions.checkNotNull(targets, "targets");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("targets", this.targets);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    CompletionsResponse other = (CompletionsResponse) obj;
+    if (this.targets == null) {
+      if (other.targets != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.targets, other.targets))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.targets== null) ? 0 : Arrays.deepHashCode(this.targets));
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ConfigurationDoneArguments.java b/java/org/eclipse/lsp4j/debug/ConfigurationDoneArguments.java
new file mode 100644
index 0000000..68a8640
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ConfigurationDoneArguments.java
@@ -0,0 +1,46 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'configurationDone' request.
+ */
+@SuppressWarnings("all")
+public class ConfigurationDoneArguments {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 1;
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ContinueArguments.java b/java/org/eclipse/lsp4j/debug/ContinueArguments.java
new file mode 100644
index 0000000..f5528f7
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ContinueArguments.java
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'continue' request.
+ */
+@SuppressWarnings("all")
+public class ContinueArguments {
+  /**
+   * Continue execution for the specified thread (if possible).
+   * <p>
+   * If the backend cannot continue on a single thread but will continue on all threads, it should set the
+   * 'allThreadsContinued' attribute in the response to true.
+   */
+  private int threadId;
+  
+  /**
+   * Continue execution for the specified thread (if possible).
+   * <p>
+   * If the backend cannot continue on a single thread but will continue on all threads, it should set the
+   * 'allThreadsContinued' attribute in the response to true.
+   */
+  @Pure
+  public int getThreadId() {
+    return this.threadId;
+  }
+  
+  /**
+   * Continue execution for the specified thread (if possible).
+   * <p>
+   * If the backend cannot continue on a single thread but will continue on all threads, it should set the
+   * 'allThreadsContinued' attribute in the response to true.
+   */
+  public void setThreadId(final int threadId) {
+    this.threadId = threadId;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("threadId", this.threadId);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ContinueArguments other = (ContinueArguments) obj;
+    if (other.threadId != this.threadId)
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + this.threadId;
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ContinueResponse.java b/java/org/eclipse/lsp4j/debug/ContinueResponse.java
new file mode 100644
index 0000000..f48aceb
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ContinueResponse.java
@@ -0,0 +1,85 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Response to 'continue' request.
+ */
+@SuppressWarnings("all")
+public class ContinueResponse {
+  /**
+   * If true, the 'continue' request has ignored the specified thread and continued all threads instead.
+   * <p>
+   * If this attribute is missing a value of 'true' is assumed for backward compatibility.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean allThreadsContinued;
+  
+  /**
+   * If true, the 'continue' request has ignored the specified thread and continued all threads instead.
+   * <p>
+   * If this attribute is missing a value of 'true' is assumed for backward compatibility.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getAllThreadsContinued() {
+    return this.allThreadsContinued;
+  }
+  
+  /**
+   * If true, the 'continue' request has ignored the specified thread and continued all threads instead.
+   * <p>
+   * If this attribute is missing a value of 'true' is assumed for backward compatibility.
+   * <p>
+   * This is an optional property.
+   */
+  public void setAllThreadsContinued(final Boolean allThreadsContinued) {
+    this.allThreadsContinued = allThreadsContinued;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("allThreadsContinued", this.allThreadsContinued);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ContinueResponse other = (ContinueResponse) obj;
+    if (this.allThreadsContinued == null) {
+      if (other.allThreadsContinued != null)
+        return false;
+    } else if (!this.allThreadsContinued.equals(other.allThreadsContinued))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.allThreadsContinued== null) ? 0 : this.allThreadsContinued.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ContinuedEventArguments.java b/java/org/eclipse/lsp4j/debug/ContinuedEventArguments.java
new file mode 100644
index 0000000..671aeda
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ContinuedEventArguments.java
@@ -0,0 +1,110 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The event indicates that the execution of the debuggee has continued.
+ * <p>
+ * Please note: a debug adapter is not expected to send this event in response to a request that implies that
+ * execution continues, e.g. 'launch' or 'continue'.
+ * <p>
+ * It is only necessary to send a 'continued' event if there was no previous request that implied this.
+ */
+@SuppressWarnings("all")
+public class ContinuedEventArguments {
+  /**
+   * The thread which was continued.
+   */
+  private int threadId;
+  
+  /**
+   * If 'allThreadsContinued' is true, a debug adapter can announce that all threads have continued.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean allThreadsContinued;
+  
+  /**
+   * The thread which was continued.
+   */
+  @Pure
+  public int getThreadId() {
+    return this.threadId;
+  }
+  
+  /**
+   * The thread which was continued.
+   */
+  public void setThreadId(final int threadId) {
+    this.threadId = threadId;
+  }
+  
+  /**
+   * If 'allThreadsContinued' is true, a debug adapter can announce that all threads have continued.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getAllThreadsContinued() {
+    return this.allThreadsContinued;
+  }
+  
+  /**
+   * If 'allThreadsContinued' is true, a debug adapter can announce that all threads have continued.
+   * <p>
+   * This is an optional property.
+   */
+  public void setAllThreadsContinued(final Boolean allThreadsContinued) {
+    this.allThreadsContinued = allThreadsContinued;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("threadId", this.threadId);
+    b.add("allThreadsContinued", this.allThreadsContinued);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ContinuedEventArguments other = (ContinuedEventArguments) obj;
+    if (other.threadId != this.threadId)
+      return false;
+    if (this.allThreadsContinued == null) {
+      if (other.allThreadsContinued != null)
+        return false;
+    } else if (!this.allThreadsContinued.equals(other.allThreadsContinued))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + this.threadId;
+    return prime * result + ((this.allThreadsContinued== null) ? 0 : this.allThreadsContinued.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/DataBreakpoint.java b/java/org/eclipse/lsp4j/debug/DataBreakpoint.java
new file mode 100644
index 0000000..9e796e6
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/DataBreakpoint.java
@@ -0,0 +1,185 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.DataBreakpointAccessType;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Properties of a data breakpoint passed to the setDataBreakpoints request.
+ */
+@SuppressWarnings("all")
+public class DataBreakpoint {
+  /**
+   * An id representing the data. This id is returned from the dataBreakpointInfo request.
+   */
+  @NonNull
+  private String dataId;
+  
+  /**
+   * The access type of the data.
+   * <p>
+   * This is an optional property.
+   */
+  private DataBreakpointAccessType accessType;
+  
+  /**
+   * An optional expression for conditional breakpoints.
+   * <p>
+   * This is an optional property.
+   */
+  private String condition;
+  
+  /**
+   * An optional expression that controls how many hits of the breakpoint are ignored.
+   * <p>
+   * The backend is expected to interpret the expression as needed.
+   * <p>
+   * This is an optional property.
+   */
+  private String hitCondition;
+  
+  /**
+   * An id representing the data. This id is returned from the dataBreakpointInfo request.
+   */
+  @Pure
+  @NonNull
+  public String getDataId() {
+    return this.dataId;
+  }
+  
+  /**
+   * An id representing the data. This id is returned from the dataBreakpointInfo request.
+   */
+  public void setDataId(@NonNull final String dataId) {
+    this.dataId = Preconditions.checkNotNull(dataId, "dataId");
+  }
+  
+  /**
+   * The access type of the data.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public DataBreakpointAccessType getAccessType() {
+    return this.accessType;
+  }
+  
+  /**
+   * The access type of the data.
+   * <p>
+   * This is an optional property.
+   */
+  public void setAccessType(final DataBreakpointAccessType accessType) {
+    this.accessType = accessType;
+  }
+  
+  /**
+   * An optional expression for conditional breakpoints.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getCondition() {
+    return this.condition;
+  }
+  
+  /**
+   * An optional expression for conditional breakpoints.
+   * <p>
+   * This is an optional property.
+   */
+  public void setCondition(final String condition) {
+    this.condition = condition;
+  }
+  
+  /**
+   * An optional expression that controls how many hits of the breakpoint are ignored.
+   * <p>
+   * The backend is expected to interpret the expression as needed.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getHitCondition() {
+    return this.hitCondition;
+  }
+  
+  /**
+   * An optional expression that controls how many hits of the breakpoint are ignored.
+   * <p>
+   * The backend is expected to interpret the expression as needed.
+   * <p>
+   * This is an optional property.
+   */
+  public void setHitCondition(final String hitCondition) {
+    this.hitCondition = hitCondition;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("dataId", this.dataId);
+    b.add("accessType", this.accessType);
+    b.add("condition", this.condition);
+    b.add("hitCondition", this.hitCondition);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DataBreakpoint other = (DataBreakpoint) obj;
+    if (this.dataId == null) {
+      if (other.dataId != null)
+        return false;
+    } else if (!this.dataId.equals(other.dataId))
+      return false;
+    if (this.accessType == null) {
+      if (other.accessType != null)
+        return false;
+    } else if (!this.accessType.equals(other.accessType))
+      return false;
+    if (this.condition == null) {
+      if (other.condition != null)
+        return false;
+    } else if (!this.condition.equals(other.condition))
+      return false;
+    if (this.hitCondition == null) {
+      if (other.hitCondition != null)
+        return false;
+    } else if (!this.hitCondition.equals(other.hitCondition))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.dataId== null) ? 0 : this.dataId.hashCode());
+    result = prime * result + ((this.accessType== null) ? 0 : this.accessType.hashCode());
+    result = prime * result + ((this.condition== null) ? 0 : this.condition.hashCode());
+    return prime * result + ((this.hitCondition== null) ? 0 : this.hitCondition.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/DataBreakpointAccessType.java b/java/org/eclipse/lsp4j/debug/DataBreakpointAccessType.java
new file mode 100644
index 0000000..4426110
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/DataBreakpointAccessType.java
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+/**
+ * This enumeration defines all possible access types for data breakpoints.
+ */
+@SuppressWarnings("all")
+public enum DataBreakpointAccessType {
+  READ,
+  
+  WRITE,
+  
+  READ_WRITE;
+}
diff --git a/java/org/eclipse/lsp4j/debug/DataBreakpointInfoArguments.java b/java/org/eclipse/lsp4j/debug/DataBreakpointInfoArguments.java
new file mode 100644
index 0000000..c1866ae
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/DataBreakpointInfoArguments.java
@@ -0,0 +1,118 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'dataBreakpointInfo' request.
+ */
+@SuppressWarnings("all")
+public class DataBreakpointInfoArguments {
+  /**
+   * Reference to the Variable container if the data breakpoint is requested for a child of the container.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer variablesReference;
+  
+  /**
+   * The name of the Variable's child to obtain data breakpoint information for.
+   * <p>
+   * If variablesReference isn’t provided, this can be an expression.
+   */
+  @NonNull
+  private String name;
+  
+  /**
+   * Reference to the Variable container if the data breakpoint is requested for a child of the container.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getVariablesReference() {
+    return this.variablesReference;
+  }
+  
+  /**
+   * Reference to the Variable container if the data breakpoint is requested for a child of the container.
+   * <p>
+   * This is an optional property.
+   */
+  public void setVariablesReference(final Integer variablesReference) {
+    this.variablesReference = variablesReference;
+  }
+  
+  /**
+   * The name of the Variable's child to obtain data breakpoint information for.
+   * <p>
+   * If variablesReference isn’t provided, this can be an expression.
+   */
+  @Pure
+  @NonNull
+  public String getName() {
+    return this.name;
+  }
+  
+  /**
+   * The name of the Variable's child to obtain data breakpoint information for.
+   * <p>
+   * If variablesReference isn’t provided, this can be an expression.
+   */
+  public void setName(@NonNull final String name) {
+    this.name = Preconditions.checkNotNull(name, "name");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("variablesReference", this.variablesReference);
+    b.add("name", this.name);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DataBreakpointInfoArguments other = (DataBreakpointInfoArguments) obj;
+    if (this.variablesReference == null) {
+      if (other.variablesReference != null)
+        return false;
+    } else if (!this.variablesReference.equals(other.variablesReference))
+      return false;
+    if (this.name == null) {
+      if (other.name != null)
+        return false;
+    } else if (!this.name.equals(other.name))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.variablesReference== null) ? 0 : this.variablesReference.hashCode());
+    return prime * result + ((this.name== null) ? 0 : this.name.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/DataBreakpointInfoResponse.java b/java/org/eclipse/lsp4j/debug/DataBreakpointInfoResponse.java
new file mode 100644
index 0000000..0ae1e9e
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/DataBreakpointInfoResponse.java
@@ -0,0 +1,180 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.lsp4j.debug.DataBreakpointAccessType;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Response to 'dataBreakpointInfo' request.
+ */
+@SuppressWarnings("all")
+public class DataBreakpointInfoResponse {
+  /**
+   * An identifier for the data on which a data breakpoint can be registered with the setDataBreakpoints request or
+   * null if no data breakpoint is available.
+   */
+  private String dataId;
+  
+  /**
+   * UI string that describes on what data the breakpoint is set on or why a data breakpoint is not available.
+   */
+  @NonNull
+  private String description;
+  
+  /**
+   * Optional attribute listing the available access types for a potential data breakpoint. A UI frontend could
+   * surface this information.
+   * <p>
+   * This is an optional property.
+   */
+  private DataBreakpointAccessType[] accessTypes;
+  
+  /**
+   * Optional attribute indicating that a potential data breakpoint could be persisted across sessions.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean canPersist;
+  
+  /**
+   * An identifier for the data on which a data breakpoint can be registered with the setDataBreakpoints request or
+   * null if no data breakpoint is available.
+   */
+  @Pure
+  public String getDataId() {
+    return this.dataId;
+  }
+  
+  /**
+   * An identifier for the data on which a data breakpoint can be registered with the setDataBreakpoints request or
+   * null if no data breakpoint is available.
+   */
+  public void setDataId(final String dataId) {
+    this.dataId = dataId;
+  }
+  
+  /**
+   * UI string that describes on what data the breakpoint is set on or why a data breakpoint is not available.
+   */
+  @Pure
+  @NonNull
+  public String getDescription() {
+    return this.description;
+  }
+  
+  /**
+   * UI string that describes on what data the breakpoint is set on or why a data breakpoint is not available.
+   */
+  public void setDescription(@NonNull final String description) {
+    this.description = Preconditions.checkNotNull(description, "description");
+  }
+  
+  /**
+   * Optional attribute listing the available access types for a potential data breakpoint. A UI frontend could
+   * surface this information.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public DataBreakpointAccessType[] getAccessTypes() {
+    return this.accessTypes;
+  }
+  
+  /**
+   * Optional attribute listing the available access types for a potential data breakpoint. A UI frontend could
+   * surface this information.
+   * <p>
+   * This is an optional property.
+   */
+  public void setAccessTypes(final DataBreakpointAccessType[] accessTypes) {
+    this.accessTypes = accessTypes;
+  }
+  
+  /**
+   * Optional attribute indicating that a potential data breakpoint could be persisted across sessions.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getCanPersist() {
+    return this.canPersist;
+  }
+  
+  /**
+   * Optional attribute indicating that a potential data breakpoint could be persisted across sessions.
+   * <p>
+   * This is an optional property.
+   */
+  public void setCanPersist(final Boolean canPersist) {
+    this.canPersist = canPersist;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("dataId", this.dataId);
+    b.add("description", this.description);
+    b.add("accessTypes", this.accessTypes);
+    b.add("canPersist", this.canPersist);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DataBreakpointInfoResponse other = (DataBreakpointInfoResponse) obj;
+    if (this.dataId == null) {
+      if (other.dataId != null)
+        return false;
+    } else if (!this.dataId.equals(other.dataId))
+      return false;
+    if (this.description == null) {
+      if (other.description != null)
+        return false;
+    } else if (!this.description.equals(other.description))
+      return false;
+    if (this.accessTypes == null) {
+      if (other.accessTypes != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.accessTypes, other.accessTypes))
+      return false;
+    if (this.canPersist == null) {
+      if (other.canPersist != null)
+        return false;
+    } else if (!this.canPersist.equals(other.canPersist))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.dataId== null) ? 0 : this.dataId.hashCode());
+    result = prime * result + ((this.description== null) ? 0 : this.description.hashCode());
+    result = prime * result + ((this.accessTypes== null) ? 0 : Arrays.deepHashCode(this.accessTypes));
+    return prime * result + ((this.canPersist== null) ? 0 : this.canPersist.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/DebugProtocol.java b/java/org/eclipse/lsp4j/debug/DebugProtocol.java
new file mode 100644
index 0000000..34e8257
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/DebugProtocol.java
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+/**
+ * Declaration of parameters, response bodies, and event bodies for
+ * the <a href="https://microsoft.github.io/debug-adapter-protocol/">Debug Adapter Protocol</a>
+ */
+@SuppressWarnings("all")
+public class DebugProtocol {
+  /**
+   * Version of Debug Protocol
+   */
+  public static final String SCHEMA_VERSION = "1.44.0";
+}
diff --git a/java/org/eclipse/lsp4j/debug/DebugProtocol.xtend b/java/org/eclipse/lsp4j/debug/DebugProtocol.xtend
new file mode 100644
index 0000000..d150bb3
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/DebugProtocol.xtend
@@ -0,0 +1,3771 @@
+/******************************************************************************
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+
+package org.eclipse.lsp4j.debug;
+
+import com.google.gson.annotations.SerializedName
+import java.util.Map
+import org.eclipse.lsp4j.generator.JsonRpcData
+import org.eclipse.lsp4j.jsonrpc.messages.Either
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull
+
+/**
+ * Declaration of parameters, response bodies, and event bodies for
+ * the <a href="https://microsoft.github.io/debug-adapter-protocol/">Debug Adapter Protocol</a>
+ */
+class DebugProtocol {
+	/**
+	 * Version of Debug Protocol
+	 */
+	public static final String SCHEMA_VERSION = "1.44.0";
+}
+
+/**
+ * Arguments for 'cancel' request.
+ */
+@JsonRpcData
+class CancelArguments {
+	/**
+	 * The ID (attribute 'seq') of the request to cancel. If missing no request is cancelled.
+	 * <p>
+	 * Both a 'requestId' and a 'progressId' can be specified in one request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer requestId;
+	/**
+	 * The ID (attribute 'progressId') of the progress to cancel. If missing no progress is cancelled.
+	 * <p>
+	 * Both a 'requestId' and a 'progressId' can be specified in one request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String progressId;
+}
+
+/**
+ * The event indicates that the execution of the debuggee has stopped due to some condition.
+ * <p>
+ * This can be caused by a break point previously set, a stepping request has completed, by executing a debugger
+ * statement etc.
+ */
+@JsonRpcData
+class StoppedEventArguments {
+	/**
+	 * The reason for the event.
+	 * <p>
+	 * For backward compatibility this string is shown in the UI if the 'description' attribute is missing (but it
+	 * must not be translated).
+	 * <p>
+	 * Possible values include - but not limited to those defined in {@link StoppedEventArgumentsReason}
+	 */
+	@NonNull
+	String reason;
+	/**
+	 * The full reason for the event, e.g. 'Paused on exception'. This string is shown in the UI as is and must be
+	 * translated.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String description;
+	/**
+	 * The thread which was stopped.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer threadId;
+	/**
+	 * A value of true hints to the frontend that this event should not change the focus.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean preserveFocusHint;
+	/**
+	 * Additional information. E.g. if reason is 'exception', text contains the exception name. This string is shown
+	 * in the UI.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String text;
+	/**
+	 * If 'allThreadsStopped' is true, a debug adapter can announce that all threads have stopped.
+	 * <ul>
+	 * <li>The client should use this information to enable that all threads can be expanded to access their
+	 * stacktraces.</li>
+	 * <li>If the attribute is missing or false, only the thread with the given threadId can be expanded.</li>
+	 * </ul>
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean allThreadsStopped;
+}
+
+/**
+ * The reason for the event.
+ * <p>
+ * For backward compatibility this string is shown in the UI if the 'description' attribute is missing (but it
+ * must not be translated).
+ * <p>
+ * Possible values include - but not limited to those defined in {@link StoppedEventArgumentsReason}
+ */
+interface StoppedEventArgumentsReason {
+	public static final String STEP = "step";
+	public static final String BREAKPOINT = "breakpoint";
+	public static final String EXCEPTION = "exception";
+	public static final String PAUSE = "pause";
+	public static final String ENTRY = "entry";
+	public static final String GOTO = "goto";
+	public static final String FUNCTION_BREAKPOINT = "function breakpoint";
+	public static final String DATA_BREAKPOINT = "data breakpoint";
+	public static final String INSTRUCTION_BREAKPOINT = "instruction breakpoint";
+}
+
+/**
+ * The event indicates that the execution of the debuggee has continued.
+ * <p>
+ * Please note: a debug adapter is not expected to send this event in response to a request that implies that
+ * execution continues, e.g. 'launch' or 'continue'.
+ * <p>
+ * It is only necessary to send a 'continued' event if there was no previous request that implied this.
+ */
+@JsonRpcData
+class ContinuedEventArguments {
+	/**
+	 * The thread which was continued.
+	 */
+	int threadId;
+	/**
+	 * If 'allThreadsContinued' is true, a debug adapter can announce that all threads have continued.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean allThreadsContinued;
+}
+
+/**
+ * The event indicates that the debuggee has exited and returns its exit code.
+ */
+@JsonRpcData
+class ExitedEventArguments {
+	/**
+	 * The exit code returned from the debuggee.
+	 */
+	int exitCode;
+}
+
+/**
+ * The event indicates that debugging of the debuggee has terminated. This does **not** mean that the debuggee
+ * itself has exited.
+ */
+@JsonRpcData
+class TerminatedEventArguments {
+	/**
+	 * A debug adapter may set 'restart' to true (or to an arbitrary object) to request that the front end restarts
+	 * the session.
+	 * <p>
+	 * The value is not interpreted by the client and passed unmodified as an attribute '__restart' to the 'launch'
+	 * and 'attach' requests.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Object restart;
+}
+
+/**
+ * The event indicates that a thread has started or exited.
+ */
+@JsonRpcData
+class ThreadEventArguments {
+	/**
+	 * The reason for the event.
+	 * <p>
+	 * Possible values include - but not limited to those defined in {@link ThreadEventArgumentsReason}
+	 */
+	@NonNull
+	String reason;
+	/**
+	 * The identifier of the thread.
+	 */
+	int threadId;
+}
+
+/**
+ * The reason for the event.
+ * <p>
+ * Possible values include - but not limited to those defined in {@link ThreadEventArgumentsReason}
+ */
+interface ThreadEventArgumentsReason {
+	public static final String STARTED = "started";
+	public static final String EXITED = "exited";
+}
+
+/**
+ * The event indicates that the target has produced some output.
+ */
+@JsonRpcData
+class OutputEventArguments {
+	/**
+	 * The output category. If not specified, 'console' is assumed.
+	 * <p>
+	 * This is an optional property.
+	 * <p>
+	 * Possible values include - but not limited to those defined in {@link OutputEventArgumentsCategory}
+	 */
+	String category;
+	/**
+	 * The output to report.
+	 */
+	@NonNull
+	String output;
+	/**
+	 * Support for keeping an output log organized by grouping related messages.
+	 * <p>
+	 * This is an optional property.
+	 */
+	OutputEventArgumentsGroup group;
+	/**
+	 * If an attribute 'variablesReference' exists and its value is &gt; 0, the output contains objects which can be
+	 * retrieved by passing 'variablesReference' to the 'variables' request. The value should be less than or equal to
+	 * 2147483647 (2^31-1).
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer variablesReference;
+	/**
+	 * An optional source location where the output was produced.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Source source;
+	/**
+	 * An optional source location line where the output was produced.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer line;
+	/**
+	 * An optional source location column where the output was produced.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer column;
+	/**
+	 * Optional data to report. For the 'telemetry' category the data will be sent to telemetry, for the other
+	 * categories the data is shown in JSON format.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Object data;
+}
+
+/**
+ * The output category. If not specified, 'console' is assumed.
+ * <p>
+ * Possible values include - but not limited to those defined in {@link OutputEventArgumentsCategory}
+ */
+interface OutputEventArgumentsCategory {
+	public static final String CONSOLE = "console";
+	public static final String STDOUT = "stdout";
+	public static final String STDERR = "stderr";
+	public static final String TELEMETRY = "telemetry";
+}
+
+/**
+ * Support for keeping an output log organized by grouping related messages.
+ */
+enum OutputEventArgumentsGroup {
+	/**
+	 * Start a new group in expanded mode. Subsequent output events are members of the group and should be shown
+	 * indented.
+	 * The 'output' attribute becomes the name of the group and is not indented.
+	 */
+	START,
+	/**
+	 * Start a new group in collapsed mode. Subsequent output events are members of the group and should be shown
+	 * indented (as soon as the group is expanded).
+	 * The 'output' attribute becomes the name of the group and is not
+	 * indented.
+	 */
+	START_COLLAPSED,
+	/**
+	 * End the current group and decreases the indentation of subsequent output events.
+	 * A non empty 'output' attribute
+	 * is shown as the unindented end of the group.
+	 */
+	END
+}
+
+/**
+ * The event indicates that some information about a breakpoint has changed.
+ */
+@JsonRpcData
+class BreakpointEventArguments {
+	/**
+	 * The reason for the event.
+	 * <p>
+	 * Possible values include - but not limited to those defined in {@link BreakpointEventArgumentsReason}
+	 */
+	@NonNull
+	String reason;
+	/**
+	 * The 'id' attribute is used to find the target breakpoint and the other attributes are used as the new values.
+	 */
+	@NonNull
+	Breakpoint breakpoint;
+}
+
+/**
+ * The reason for the event.
+ * <p>
+ * Possible values include - but not limited to those defined in {@link BreakpointEventArgumentsReason}
+ */
+interface BreakpointEventArgumentsReason {
+	public static final String CHANGED = "changed";
+	public static final String NEW = "new";
+	public static final String REMOVED = "removed";
+}
+
+/**
+ * The event indicates that some information about a module has changed.
+ */
+@JsonRpcData
+class ModuleEventArguments {
+	/**
+	 * The reason for the event.
+	 */
+	@NonNull
+	ModuleEventArgumentsReason reason;
+	/**
+	 * The new, changed, or removed module. In case of 'removed' only the module id is used.
+	 */
+	@NonNull
+	Module module;
+}
+
+/**
+ * The reason for the event.
+ */
+enum ModuleEventArgumentsReason {
+	NEW,
+	CHANGED,
+	REMOVED
+}
+
+/**
+ * The event indicates that some source has been added, changed, or removed from the set of all loaded sources.
+ */
+@JsonRpcData
+class LoadedSourceEventArguments {
+	/**
+	 * The reason for the event.
+	 */
+	@NonNull
+	LoadedSourceEventArgumentsReason reason;
+	/**
+	 * The new, changed, or removed source.
+	 */
+	@NonNull
+	Source source;
+}
+
+/**
+ * The reason for the event.
+ */
+enum LoadedSourceEventArgumentsReason {
+	NEW,
+	CHANGED,
+	REMOVED
+}
+
+/**
+ * The event indicates that the debugger has begun debugging a new process. Either one that it has launched, or
+ * one that it has attached to.
+ */
+@JsonRpcData
+class ProcessEventArguments {
+	/**
+	 * The logical name of the process. This is usually the full path to process's executable file. Example:
+	 * /home/example/myproj/program.js.
+	 */
+	@NonNull
+	String name;
+	/**
+	 * The system process id of the debugged process. This property will be missing for non-system processes.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer systemProcessId;
+	/**
+	 * If true, the process is running on the same computer as the debug adapter.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean isLocalProcess;
+	/**
+	 * Describes how the debug engine started debugging this process.
+	 * <p>
+	 * This is an optional property.
+	 */
+	ProcessEventArgumentsStartMethod startMethod;
+	/**
+	 * The size of a pointer or address for this process, in bits. This value may be used by clients when formatting
+	 * addresses for display.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer pointerSize;
+}
+
+/**
+ * Describes how the debug engine started debugging this process.
+ */
+enum ProcessEventArgumentsStartMethod {
+	/**
+	 * Process was launched under the debugger.
+	 */
+	LAUNCH,
+	/**
+	 * Debugger attached to an existing process.
+	 */
+	ATTACH,
+	/**
+	 * A project launcher component has launched a new process in a suspended state and then asked the debugger to
+	 * attach.
+	 */
+	ATTACH_FOR_SUSPENDED_LAUNCH
+}
+
+/**
+ * The event indicates that one or more capabilities have changed.
+ * <p>
+ * Since the capabilities are dependent on the frontend and its UI, it might not be possible to change that at
+ * random times (or too late).
+ * <p>
+ * Consequently this event has a hint characteristic: a frontend can only be expected to make a 'best effort' in
+ * honouring individual capabilities but there are no guarantees.
+ * <p>
+ * Only changed capabilities need to be included, all other capabilities keep their values.
+ */
+@JsonRpcData
+class CapabilitiesEventArguments {
+	/**
+	 * The set of updated capabilities.
+	 */
+	@NonNull
+	Capabilities capabilities;
+}
+
+/**
+ * The event signals that a long running operation is about to start and
+ * <p>
+ * provides additional information for the client to set up a corresponding progress and cancellation UI.
+ * <p>
+ * The client is free to delay the showing of the UI in order to reduce flicker.
+ * <p>
+ * This event should only be sent if the client has passed the value true for the 'supportsProgressReporting'
+ * capability of the 'initialize' request.
+ */
+@JsonRpcData
+class ProgressStartEventArguments {
+	/**
+	 * An ID that must be used in subsequent 'progressUpdate' and 'progressEnd' events to make them refer to the same
+	 * progress reporting.
+	 * <p>
+	 * IDs must be unique within a debug session.
+	 */
+	@NonNull
+	String progressId;
+	/**
+	 * Mandatory (short) title of the progress reporting. Shown in the UI to describe the long running operation.
+	 */
+	@NonNull
+	String title;
+	/**
+	 * The request ID that this progress report is related to. If specified a debug adapter is expected to emit
+	 * <p>
+	 * progress events for the long running request until the request has been either completed or cancelled.
+	 * <p>
+	 * If the request ID is omitted, the progress report is assumed to be related to some general activity of the
+	 * debug adapter.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer requestId;
+	/**
+	 * If true, the request that reports progress may be canceled with a 'cancel' request.
+	 * <p>
+	 * So this property basically controls whether the client should use UX that supports cancellation.
+	 * <p>
+	 * Clients that don't support cancellation are allowed to ignore the setting.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean cancellable;
+	/**
+	 * Optional, more detailed progress message.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String message;
+	/**
+	 * Optional progress percentage to display (value range: 0 to 100). If omitted no percentage will be shown.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Double percentage;
+}
+
+/**
+ * The event signals that the progress reporting needs to updated with a new message and/or percentage.
+ * <p>
+ * The client does not have to update the UI immediately, but the clients needs to keep track of the message
+ * and/or percentage values.
+ * <p>
+ * This event should only be sent if the client has passed the value true for the 'supportsProgressReporting'
+ * capability of the 'initialize' request.
+ */
+@JsonRpcData
+class ProgressUpdateEventArguments {
+	/**
+	 * The ID that was introduced in the initial 'progressStart' event.
+	 */
+	@NonNull
+	String progressId;
+	/**
+	 * Optional, more detailed progress message. If omitted, the previous message (if any) is used.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String message;
+	/**
+	 * Optional progress percentage to display (value range: 0 to 100). If omitted no percentage will be shown.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Double percentage;
+}
+
+/**
+ * The event signals the end of the progress reporting with an optional final message.
+ * <p>
+ * This event should only be sent if the client has passed the value true for the 'supportsProgressReporting'
+ * capability of the 'initialize' request.
+ */
+@JsonRpcData
+class ProgressEndEventArguments {
+	/**
+	 * The ID that was introduced in the initial 'ProgressStartEvent'.
+	 */
+	@NonNull
+	String progressId;
+	/**
+	 * Optional, more detailed progress message. If omitted, the previous message (if any) is used.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String message;
+}
+
+/**
+ * This event signals that some state in the debug adapter has changed and requires that the client needs to
+ * re-render the data snapshot previously requested.
+ * <p>
+ * Debug adapters do not have to emit this event for runtime changes like stopped or thread events because in that
+ * case the client refetches the new state anyway. But the event can be used for example to refresh the UI after
+ * rendering formatting has changed in the debug adapter.
+ * <p>
+ * This event should only be sent if the debug adapter has received a value true for the
+ * 'supportsInvalidatedEvent' capability of the 'initialize' request.
+ */
+@JsonRpcData
+class InvalidatedEventArguments {
+	/**
+	 * Optional set of logical areas that got invalidated. This property has a hint characteristic: a client can only
+	 * be expected to make a 'best effort' in honouring the areas but there are no guarantees. If this property is
+	 * missing, empty, or if values are not understand the client should assume a single value 'all'.
+	 * <p>
+	 * This is an optional property.
+	 * <p>
+	 * Possible values include - but not limited to those defined in {@link InvalidatedAreas}
+	 */
+	String[] areas;
+	/**
+	 * If specified, the client only needs to refetch data related to this thread.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer threadId;
+	/**
+	 * If specified, the client only needs to refetch data related to this stack frame (and the 'threadId' is
+	 * ignored).
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer stackFrameId;
+}
+
+/**
+ * Response to 'runInTerminal' request.
+ */
+@JsonRpcData
+class RunInTerminalResponse {
+	/**
+	 * The process ID. The value should be less than or equal to 2147483647 (2^31-1).
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer processId;
+	/**
+	 * The process ID of the terminal shell. The value should be less than or equal to 2147483647 (2^31-1).
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer shellProcessId;
+}
+
+/**
+ * Arguments for 'runInTerminal' request.
+ */
+@JsonRpcData
+class RunInTerminalRequestArguments {
+	/**
+	 * What kind of terminal to launch.
+	 * <p>
+	 * This is an optional property.
+	 */
+	RunInTerminalRequestArgumentsKind kind;
+	/**
+	 * Optional title of the terminal.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String title;
+	/**
+	 * Working directory for the command. For non-empty, valid paths this typically results in execution of a change
+	 * directory command.
+	 */
+	@NonNull
+	String cwd;
+	/**
+	 * List of arguments. The first argument is the command to run.
+	 */
+	@NonNull
+	String[] args;
+	/**
+	 * Environment key-value pairs that are added to or removed from the default environment.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Map<String, String> env;
+}
+
+/**
+ * What kind of terminal to launch.
+ */
+enum RunInTerminalRequestArgumentsKind {
+	INTEGRATED,
+	EXTERNAL
+}
+
+/**
+ * Arguments for 'initialize' request.
+ */
+@JsonRpcData
+class InitializeRequestArguments {
+	/**
+	 * The ID of the (frontend) client using this adapter.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String clientID;
+	/**
+	 * The human readable name of the (frontend) client using this adapter.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String clientName;
+	/**
+	 * The ID of the debug adapter.
+	 */
+	@NonNull
+	String adapterID;
+	/**
+	 * The ISO-639 locale of the (frontend) client using this adapter, e.g. en-US or de-CH.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String locale;
+	/**
+	 * If true all line numbers are 1-based (default).
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean linesStartAt1;
+	/**
+	 * If true all column numbers are 1-based (default).
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean columnsStartAt1;
+	/**
+	 * Determines in what format paths are specified. The default is 'path', which is the native format.
+	 * <p>
+	 * This is an optional property.
+	 * <p>
+	 * Possible values include - but not limited to those defined in {@link InitializeRequestArgumentsPathFormat}
+	 */
+	String pathFormat;
+	/**
+	 * Client supports the optional type attribute for variables.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsVariableType;
+	/**
+	 * Client supports the paging of variables.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsVariablePaging;
+	/**
+	 * Client supports the runInTerminal request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsRunInTerminalRequest;
+	/**
+	 * Client supports memory references.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsMemoryReferences;
+	/**
+	 * Client supports progress reporting.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsProgressReporting;
+	/**
+	 * Client supports the invalidated event.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsInvalidatedEvent;
+}
+
+/**
+ * Determines in what format paths are specified. The default is 'path', which is the native format.
+ * <p>
+ * Possible values include - but not limited to those defined in {@link InitializeRequestArgumentsPathFormat}
+ */
+interface InitializeRequestArgumentsPathFormat {
+	public static final String PATH = "path";
+	public static final String URI = "uri";
+}
+
+/**
+ * Arguments for 'configurationDone' request.
+ */
+@JsonRpcData
+class ConfigurationDoneArguments {
+}
+
+/**
+ * Arguments for 'launch' request. Additional attributes are implementation specific.
+ */
+@JsonRpcData
+class LaunchRequestArguments {
+	/**
+	 * If noDebug is true the launch request should launch the program without enabling debugging.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean noDebug;
+	/**
+	 * Optional data from the previous, restarted session.
+	 * <p>
+	 * The data is sent as the 'restart' attribute of the 'terminated' event.
+	 * <p>
+	 * The client should leave the data intact.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Object __restart;
+}
+
+/**
+ * Arguments for 'attach' request. Additional attributes are implementation specific.
+ */
+@JsonRpcData
+class AttachRequestArguments {
+	/**
+	 * Optional data from the previous, restarted session.
+	 * <p>
+	 * The data is sent as the 'restart' attribute of the 'terminated' event.
+	 * <p>
+	 * The client should leave the data intact.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Object __restart;
+}
+
+/**
+ * Arguments for 'restart' request.
+ */
+@JsonRpcData
+class RestartArguments {
+}
+
+/**
+ * Arguments for 'disconnect' request.
+ */
+@JsonRpcData
+class DisconnectArguments {
+	/**
+	 * A value of true indicates that this 'disconnect' request is part of a restart sequence.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean restart;
+	/**
+	 * Indicates whether the debuggee should be terminated when the debugger is disconnected.
+	 * <p>
+	 * If unspecified, the debug adapter is free to do whatever it thinks is best.
+	 * <p>
+	 * The attribute is only honored by a debug adapter if the capability 'supportTerminateDebuggee' is true.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean terminateDebuggee;
+}
+
+/**
+ * Arguments for 'terminate' request.
+ */
+@JsonRpcData
+class TerminateArguments {
+	/**
+	 * A value of true indicates that this 'terminate' request is part of a restart sequence.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean restart;
+}
+
+/**
+ * Response to 'breakpointLocations' request.
+ * <p>
+ * Contains possible locations for source breakpoints.
+ */
+@JsonRpcData
+class BreakpointLocationsResponse {
+	/**
+	 * Sorted set of possible breakpoint locations.
+	 */
+	@NonNull
+	BreakpointLocation[] breakpoints;
+}
+
+/**
+ * Arguments for 'breakpointLocations' request.
+ */
+@JsonRpcData
+class BreakpointLocationsArguments {
+	/**
+	 * The source location of the breakpoints; either 'source.path' or 'source.reference' must be specified.
+	 */
+	@NonNull
+	Source source;
+	/**
+	 * Start line of range to search possible breakpoint locations in. If only the line is specified, the request
+	 * returns all possible locations in that line.
+	 */
+	int line;
+	/**
+	 * Optional start column of range to search possible breakpoint locations in. If no start column is given, the
+	 * first column in the start line is assumed.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer column;
+	/**
+	 * Optional end line of range to search possible breakpoint locations in. If no end line is given, then the end
+	 * line is assumed to be the start line.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer endLine;
+	/**
+	 * Optional end column of range to search possible breakpoint locations in. If no end column is given, then it is
+	 * assumed to be in the last column of the end line.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer endColumn;
+}
+
+/**
+ * Response to 'setBreakpoints' request.
+ * <p>
+ * Returned is information about each breakpoint created by this request.
+ * <p>
+ * This includes the actual code location and whether the breakpoint could be verified.
+ * <p>
+ * The breakpoints returned are in the same order as the elements of the 'breakpoints'
+ * <p>
+ * (or the deprecated 'lines') array in the arguments.
+ */
+@JsonRpcData
+class SetBreakpointsResponse {
+	/**
+	 * Information about the breakpoints.
+	 * <p>
+	 * The array elements are in the same order as the elements of the 'breakpoints' (or the deprecated 'lines') array
+	 * in the arguments.
+	 */
+	@NonNull
+	Breakpoint[] breakpoints;
+}
+
+/**
+ * Arguments for 'setBreakpoints' request.
+ */
+@JsonRpcData
+class SetBreakpointsArguments {
+	/**
+	 * The source location of the breakpoints; either 'source.path' or 'source.reference' must be specified.
+	 */
+	@NonNull
+	Source source;
+	/**
+	 * The code locations of the breakpoints.
+	 * <p>
+	 * This is an optional property.
+	 */
+	SourceBreakpoint[] breakpoints;
+	/**
+	 * Deprecated: The code locations of the breakpoints.
+	 * <p>
+	 * This is an optional property.
+	 * <p>
+	 * @deprecated Use the line field in the breakpoints property instead.
+	 */
+	@Deprecated
+	int[] lines;
+	/**
+	 * A value of true indicates that the underlying source has been modified which results in new breakpoint
+	 * locations.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean sourceModified;
+}
+
+/**
+ * Response to 'setFunctionBreakpoints' request.
+ * <p>
+ * Returned is information about each breakpoint created by this request.
+ */
+@JsonRpcData
+class SetFunctionBreakpointsResponse {
+	/**
+	 * Information about the breakpoints. The array elements correspond to the elements of the 'breakpoints' array.
+	 */
+	@NonNull
+	Breakpoint[] breakpoints;
+}
+
+/**
+ * Arguments for 'setFunctionBreakpoints' request.
+ */
+@JsonRpcData
+class SetFunctionBreakpointsArguments {
+	/**
+	 * The function names of the breakpoints.
+	 */
+	@NonNull
+	FunctionBreakpoint[] breakpoints;
+}
+
+/**
+ * Arguments for 'setExceptionBreakpoints' request.
+ */
+@JsonRpcData
+class SetExceptionBreakpointsArguments {
+	/**
+	 * Set of exception filters specified by their ID. The set of all possible exception filters is defined by the
+	 * 'exceptionBreakpointFilters' capability. The 'filter' and 'filterOptions' sets are additive.
+	 */
+	@NonNull
+	String[] filters;
+	/**
+	 * Set of exception filters and their options. The set of all possible exception filters is defined by the
+	 * 'exceptionBreakpointFilters' capability. This attribute is only honored by a debug adapter if the capability
+	 * 'supportsExceptionFilterOptions' is true. The 'filter' and 'filterOptions' sets are additive.
+	 * <p>
+	 * This is an optional property.
+	 */
+	ExceptionFilterOptions[] filterOptions;
+	/**
+	 * Configuration options for selected exceptions.
+	 * <p>
+	 * The attribute is only honored by a debug adapter if the capability 'supportsExceptionOptions' is true.
+	 * <p>
+	 * This is an optional property.
+	 */
+	ExceptionOptions[] exceptionOptions;
+}
+
+/**
+ * Response to 'dataBreakpointInfo' request.
+ */
+@JsonRpcData
+class DataBreakpointInfoResponse {
+	/**
+	 * An identifier for the data on which a data breakpoint can be registered with the setDataBreakpoints request or
+	 * null if no data breakpoint is available.
+	 */
+	String dataId;
+	/**
+	 * UI string that describes on what data the breakpoint is set on or why a data breakpoint is not available.
+	 */
+	@NonNull
+	String description;
+	/**
+	 * Optional attribute listing the available access types for a potential data breakpoint. A UI frontend could
+	 * surface this information.
+	 * <p>
+	 * This is an optional property.
+	 */
+	DataBreakpointAccessType[] accessTypes;
+	/**
+	 * Optional attribute indicating that a potential data breakpoint could be persisted across sessions.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean canPersist;
+}
+
+/**
+ * Arguments for 'dataBreakpointInfo' request.
+ */
+@JsonRpcData
+class DataBreakpointInfoArguments {
+	/**
+	 * Reference to the Variable container if the data breakpoint is requested for a child of the container.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer variablesReference;
+	/**
+	 * The name of the Variable's child to obtain data breakpoint information for.
+	 * <p>
+	 * If variablesReference isn’t provided, this can be an expression.
+	 */
+	@NonNull
+	String name;
+}
+
+/**
+ * Response to 'setDataBreakpoints' request.
+ * <p>
+ * Returned is information about each breakpoint created by this request.
+ */
+@JsonRpcData
+class SetDataBreakpointsResponse {
+	/**
+	 * Information about the data breakpoints. The array elements correspond to the elements of the input argument
+	 * 'breakpoints' array.
+	 */
+	@NonNull
+	Breakpoint[] breakpoints;
+}
+
+/**
+ * Arguments for 'setDataBreakpoints' request.
+ */
+@JsonRpcData
+class SetDataBreakpointsArguments {
+	/**
+	 * The contents of this array replaces all existing data breakpoints. An empty array clears all data breakpoints.
+	 */
+	@NonNull
+	DataBreakpoint[] breakpoints;
+}
+
+/**
+ * Response to 'setInstructionBreakpoints' request
+ */
+@JsonRpcData
+class SetInstructionBreakpointsResponse {
+	/**
+	 * Information about the breakpoints. The array elements correspond to the elements of the 'breakpoints' array.
+	 */
+	@NonNull
+	Breakpoint[] breakpoints;
+}
+
+/**
+ * Arguments for 'setInstructionBreakpoints' request
+ */
+@JsonRpcData
+class SetInstructionBreakpointsArguments {
+	/**
+	 * The instruction references of the breakpoints
+	 */
+	@NonNull
+	InstructionBreakpoint[] breakpoints;
+}
+
+/**
+ * Response to 'continue' request.
+ */
+@JsonRpcData
+class ContinueResponse {
+	/**
+	 * If true, the 'continue' request has ignored the specified thread and continued all threads instead.
+	 * <p>
+	 * If this attribute is missing a value of 'true' is assumed for backward compatibility.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean allThreadsContinued;
+}
+
+/**
+ * Arguments for 'continue' request.
+ */
+@JsonRpcData
+class ContinueArguments {
+	/**
+	 * Continue execution for the specified thread (if possible).
+	 * <p>
+	 * If the backend cannot continue on a single thread but will continue on all threads, it should set the
+	 * 'allThreadsContinued' attribute in the response to true.
+	 */
+	int threadId;
+}
+
+/**
+ * Arguments for 'next' request.
+ */
+@JsonRpcData
+class NextArguments {
+	/**
+	 * Execute 'next' for this thread.
+	 */
+	int threadId;
+	/**
+	 * Optional granularity to step. If no granularity is specified, a granularity of 'statement' is assumed.
+	 * <p>
+	 * This is an optional property.
+	 */
+	SteppingGranularity granularity;
+}
+
+/**
+ * Arguments for 'stepIn' request.
+ */
+@JsonRpcData
+class StepInArguments {
+	/**
+	 * Execute 'stepIn' for this thread.
+	 */
+	int threadId;
+	/**
+	 * Optional id of the target to step into.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer targetId;
+	/**
+	 * Optional granularity to step. If no granularity is specified, a granularity of 'statement' is assumed.
+	 * <p>
+	 * This is an optional property.
+	 */
+	SteppingGranularity granularity;
+}
+
+/**
+ * Arguments for 'stepOut' request.
+ */
+@JsonRpcData
+class StepOutArguments {
+	/**
+	 * Execute 'stepOut' for this thread.
+	 */
+	int threadId;
+	/**
+	 * Optional granularity to step. If no granularity is specified, a granularity of 'statement' is assumed.
+	 * <p>
+	 * This is an optional property.
+	 */
+	SteppingGranularity granularity;
+}
+
+/**
+ * Arguments for 'stepBack' request.
+ */
+@JsonRpcData
+class StepBackArguments {
+	/**
+	 * Execute 'stepBack' for this thread.
+	 */
+	int threadId;
+	/**
+	 * Optional granularity to step. If no granularity is specified, a granularity of 'statement' is assumed.
+	 * <p>
+	 * This is an optional property.
+	 */
+	SteppingGranularity granularity;
+}
+
+/**
+ * Arguments for 'reverseContinue' request.
+ */
+@JsonRpcData
+class ReverseContinueArguments {
+	/**
+	 * Execute 'reverseContinue' for this thread.
+	 */
+	int threadId;
+}
+
+/**
+ * Arguments for 'restartFrame' request.
+ */
+@JsonRpcData
+class RestartFrameArguments {
+	/**
+	 * Restart this stackframe.
+	 */
+	int frameId;
+}
+
+/**
+ * Arguments for 'goto' request.
+ */
+@JsonRpcData
+class GotoArguments {
+	/**
+	 * Set the goto target for this thread.
+	 */
+	int threadId;
+	/**
+	 * The location where the debuggee will continue to run.
+	 */
+	int targetId;
+}
+
+/**
+ * Arguments for 'pause' request.
+ */
+@JsonRpcData
+class PauseArguments {
+	/**
+	 * Pause execution for this thread.
+	 */
+	int threadId;
+}
+
+/**
+ * Response to 'stackTrace' request.
+ */
+@JsonRpcData
+class StackTraceResponse {
+	/**
+	 * The frames of the stackframe. If the array has length zero, there are no stackframes available.
+	 * <p>
+	 * This means that there is no location information available.
+	 */
+	@NonNull
+	StackFrame[] stackFrames;
+	/**
+	 * The total number of frames available in the stack. If omitted or if totalFrames is larger than the available
+	 * frames, a client is expected to request frames until a request returns less frames than requested (which
+	 * indicates the end of the stack). Returning monotonically increasing totalFrames values for subsequent requests
+	 * can be used to enforce paging in the client.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer totalFrames;
+}
+
+/**
+ * Arguments for 'stackTrace' request.
+ */
+@JsonRpcData
+class StackTraceArguments {
+	/**
+	 * Retrieve the stacktrace for this thread.
+	 */
+	int threadId;
+	/**
+	 * The index of the first frame to return; if omitted frames start at 0.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer startFrame;
+	/**
+	 * The maximum number of frames to return. If levels is not specified or 0, all frames are returned.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer levels;
+	/**
+	 * Specifies details on how to format the stack frames.
+	 * <p>
+	 * The attribute is only honored by a debug adapter if the capability 'supportsValueFormattingOptions' is true.
+	 * <p>
+	 * This is an optional property.
+	 */
+	StackFrameFormat format;
+}
+
+/**
+ * Response to 'scopes' request.
+ */
+@JsonRpcData
+class ScopesResponse {
+	/**
+	 * The scopes of the stackframe. If the array has length zero, there are no scopes available.
+	 */
+	@NonNull
+	Scope[] scopes;
+}
+
+/**
+ * Arguments for 'scopes' request.
+ */
+@JsonRpcData
+class ScopesArguments {
+	/**
+	 * Retrieve the scopes for this stackframe.
+	 */
+	int frameId;
+}
+
+/**
+ * Response to 'variables' request.
+ */
+@JsonRpcData
+class VariablesResponse {
+	/**
+	 * All (or a range) of variables for the given variable reference.
+	 */
+	@NonNull
+	Variable[] variables;
+}
+
+/**
+ * Arguments for 'variables' request.
+ */
+@JsonRpcData
+class VariablesArguments {
+	/**
+	 * The Variable reference.
+	 */
+	int variablesReference;
+	/**
+	 * Optional filter to limit the child variables to either named or indexed. If omitted, both types are fetched.
+	 * <p>
+	 * This is an optional property.
+	 */
+	VariablesArgumentsFilter filter;
+	/**
+	 * The index of the first variable to return; if omitted children start at 0.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer start;
+	/**
+	 * The number of variables to return. If count is missing or 0, all variables are returned.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer count;
+	/**
+	 * Specifies details on how to format the Variable values.
+	 * <p>
+	 * The attribute is only honored by a debug adapter if the capability 'supportsValueFormattingOptions' is true.
+	 * <p>
+	 * This is an optional property.
+	 */
+	ValueFormat format;
+}
+
+/**
+ * Optional filter to limit the child variables to either named or indexed. If omitted, both types are fetched.
+ */
+enum VariablesArgumentsFilter {
+	INDEXED,
+	NAMED
+}
+
+/**
+ * Response to 'setVariable' request.
+ */
+@JsonRpcData
+class SetVariableResponse {
+	/**
+	 * The new value of the variable.
+	 */
+	@NonNull
+	String value;
+	/**
+	 * The type of the new value. Typically shown in the UI when hovering over the value.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String type;
+	/**
+	 * If variablesReference is &gt; 0, the new value is structured and its children can be retrieved by passing
+	 * variablesReference to the VariablesRequest.
+	 * <p>
+	 * The value should be less than or equal to 2147483647 (2^31-1).
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer variablesReference;
+	/**
+	 * The number of named child variables.
+	 * <p>
+	 * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+	 * <p>
+	 * The value should be less than or equal to 2147483647 (2^31-1).
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer namedVariables;
+	/**
+	 * The number of indexed child variables.
+	 * <p>
+	 * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+	 * <p>
+	 * The value should be less than or equal to 2147483647 (2^31-1).
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer indexedVariables;
+}
+
+/**
+ * Arguments for 'setVariable' request.
+ */
+@JsonRpcData
+class SetVariableArguments {
+	/**
+	 * The reference of the variable container.
+	 */
+	int variablesReference;
+	/**
+	 * The name of the variable in the container.
+	 */
+	@NonNull
+	String name;
+	/**
+	 * The value of the variable.
+	 */
+	@NonNull
+	String value;
+	/**
+	 * Specifies details on how to format the response value.
+	 * <p>
+	 * This is an optional property.
+	 */
+	ValueFormat format;
+}
+
+/**
+ * Response to 'source' request.
+ */
+@JsonRpcData
+class SourceResponse {
+	/**
+	 * Content of the source reference.
+	 */
+	@NonNull
+	String content;
+	/**
+	 * Optional content type (mime type) of the source.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String mimeType;
+}
+
+/**
+ * Arguments for 'source' request.
+ */
+@JsonRpcData
+class SourceArguments {
+	/**
+	 * Specifies the source content to load. Either source.path or source.sourceReference must be specified.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Source source;
+	/**
+	 * The reference to the source. This is the same as source.sourceReference.
+	 * <p>
+	 * This is provided for backward compatibility since old backends do not understand the 'source' attribute.
+	 */
+	int sourceReference;
+}
+
+/**
+ * Response to 'threads' request.
+ */
+@JsonRpcData
+class ThreadsResponse {
+	/**
+	 * All threads.
+	 */
+	@NonNull
+	Thread[] threads;
+}
+
+/**
+ * Arguments for 'terminateThreads' request.
+ */
+@JsonRpcData
+class TerminateThreadsArguments {
+	/**
+	 * Ids of threads to be terminated.
+	 * <p>
+	 * This is an optional property.
+	 */
+	int[] threadIds;
+}
+
+/**
+ * Response to 'modules' request.
+ */
+@JsonRpcData
+class ModulesResponse {
+	/**
+	 * All modules or range of modules.
+	 */
+	@NonNull
+	Module[] modules;
+	/**
+	 * The total number of modules available.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer totalModules;
+}
+
+/**
+ * Arguments for 'modules' request.
+ */
+@JsonRpcData
+class ModulesArguments {
+	/**
+	 * The index of the first module to return; if omitted modules start at 0.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer startModule;
+	/**
+	 * The number of modules to return. If moduleCount is not specified or 0, all modules are returned.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer moduleCount;
+}
+
+/**
+ * Response to 'loadedSources' request.
+ */
+@JsonRpcData
+class LoadedSourcesResponse {
+	/**
+	 * Set of loaded sources.
+	 */
+	@NonNull
+	Source[] sources;
+}
+
+/**
+ * Arguments for 'loadedSources' request.
+ */
+@JsonRpcData
+class LoadedSourcesArguments {
+}
+
+/**
+ * Response to 'evaluate' request.
+ */
+@JsonRpcData
+class EvaluateResponse {
+	/**
+	 * The result of the evaluate request.
+	 */
+	@NonNull
+	String result;
+	/**
+	 * The optional type of the evaluate result.
+	 * <p>
+	 * This attribute should only be returned by a debug adapter if the client has passed the value true for the
+	 * 'supportsVariableType' capability of the 'initialize' request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String type;
+	/**
+	 * Properties of a evaluate result that can be used to determine how to render the result in the UI.
+	 * <p>
+	 * This is an optional property.
+	 */
+	VariablePresentationHint presentationHint;
+	/**
+	 * If variablesReference is &gt; 0, the evaluate result is structured and its children can be retrieved by passing
+	 * variablesReference to the VariablesRequest.
+	 * <p>
+	 * The value should be less than or equal to 2147483647 (2^31-1).
+	 */
+	int variablesReference;
+	/**
+	 * The number of named child variables.
+	 * <p>
+	 * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+	 * <p>
+	 * The value should be less than or equal to 2147483647 (2^31-1).
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer namedVariables;
+	/**
+	 * The number of indexed child variables.
+	 * <p>
+	 * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+	 * <p>
+	 * The value should be less than or equal to 2147483647 (2^31-1).
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer indexedVariables;
+	/**
+	 * Optional memory reference to a location appropriate for this result.
+	 * <p>
+	 * For pointer type eval results, this is generally a reference to the memory address contained in the pointer.
+	 * <p>
+	 * This attribute should be returned by a debug adapter if the client has passed the value true for the
+	 * 'supportsMemoryReferences' capability of the 'initialize' request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String memoryReference;
+}
+
+/**
+ * Arguments for 'evaluate' request.
+ */
+@JsonRpcData
+class EvaluateArguments {
+	/**
+	 * The expression to evaluate.
+	 */
+	@NonNull
+	String expression;
+	/**
+	 * Evaluate the expression in the scope of this stack frame. If not specified, the expression is evaluated in the
+	 * global scope.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer frameId;
+	/**
+	 * The context in which the evaluate request is run.
+	 * <p>
+	 * This is an optional property.
+	 * <p>
+	 * Possible values include - but not limited to those defined in {@link EvaluateArgumentsContext}
+	 */
+	String context;
+	/**
+	 * Specifies details on how to format the Evaluate result.
+	 * <p>
+	 * The attribute is only honored by a debug adapter if the capability 'supportsValueFormattingOptions' is true.
+	 * <p>
+	 * This is an optional property.
+	 */
+	ValueFormat format;
+}
+
+/**
+ * The context in which the evaluate request is run.
+ * <p>
+ * Possible values include - but not limited to those defined in {@link EvaluateArgumentsContext}
+ */
+interface EvaluateArgumentsContext {
+	/**
+	 * evaluate is run in a watch.
+	 */
+	public static final String WATCH = "watch";
+	/**
+	 * evaluate is run from REPL console.
+	 */
+	public static final String REPL = "repl";
+	/**
+	 * evaluate is run from a data hover.
+	 */
+	public static final String HOVER = "hover";
+	/**
+	 * evaluate is run to generate the value that will be stored in the clipboard.
+	 * The attribute is only honored by a
+	 * debug adapter if the capability 'supportsClipboardContext' is true.
+	 */
+	public static final String CLIPBOARD = "clipboard";
+}
+
+/**
+ * Response to 'setExpression' request.
+ */
+@JsonRpcData
+class SetExpressionResponse {
+	/**
+	 * The new value of the expression.
+	 */
+	@NonNull
+	String value;
+	/**
+	 * The optional type of the value.
+	 * <p>
+	 * This attribute should only be returned by a debug adapter if the client has passed the value true for the
+	 * 'supportsVariableType' capability of the 'initialize' request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String type;
+	/**
+	 * Properties of a value that can be used to determine how to render the result in the UI.
+	 * <p>
+	 * This is an optional property.
+	 */
+	VariablePresentationHint presentationHint;
+	/**
+	 * If variablesReference is &gt; 0, the value is structured and its children can be retrieved by passing
+	 * variablesReference to the VariablesRequest.
+	 * <p>
+	 * The value should be less than or equal to 2147483647 (2^31-1).
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer variablesReference;
+	/**
+	 * The number of named child variables.
+	 * <p>
+	 * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+	 * <p>
+	 * The value should be less than or equal to 2147483647 (2^31-1).
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer namedVariables;
+	/**
+	 * The number of indexed child variables.
+	 * <p>
+	 * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+	 * <p>
+	 * The value should be less than or equal to 2147483647 (2^31-1).
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer indexedVariables;
+}
+
+/**
+ * Arguments for 'setExpression' request.
+ */
+@JsonRpcData
+class SetExpressionArguments {
+	/**
+	 * The l-value expression to assign to.
+	 */
+	@NonNull
+	String expression;
+	/**
+	 * The value expression to assign to the l-value expression.
+	 */
+	@NonNull
+	String value;
+	/**
+	 * Evaluate the expressions in the scope of this stack frame. If not specified, the expressions are evaluated in
+	 * the global scope.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer frameId;
+	/**
+	 * Specifies how the resulting value should be formatted.
+	 * <p>
+	 * This is an optional property.
+	 */
+	ValueFormat format;
+}
+
+/**
+ * Response to 'stepInTargets' request.
+ */
+@JsonRpcData
+class StepInTargetsResponse {
+	/**
+	 * The possible stepIn targets of the specified source location.
+	 */
+	@NonNull
+	StepInTarget[] targets;
+}
+
+/**
+ * Arguments for 'stepInTargets' request.
+ */
+@JsonRpcData
+class StepInTargetsArguments {
+	/**
+	 * The stack frame for which to retrieve the possible stepIn targets.
+	 */
+	int frameId;
+}
+
+/**
+ * Response to 'gotoTargets' request.
+ */
+@JsonRpcData
+class GotoTargetsResponse {
+	/**
+	 * The possible goto targets of the specified location.
+	 */
+	@NonNull
+	GotoTarget[] targets;
+}
+
+/**
+ * Arguments for 'gotoTargets' request.
+ */
+@JsonRpcData
+class GotoTargetsArguments {
+	/**
+	 * The source location for which the goto targets are determined.
+	 */
+	@NonNull
+	Source source;
+	/**
+	 * The line location for which the goto targets are determined.
+	 */
+	int line;
+	/**
+	 * An optional column location for which the goto targets are determined.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer column;
+}
+
+/**
+ * Response to 'completions' request.
+ */
+@JsonRpcData
+class CompletionsResponse {
+	/**
+	 * The possible completions for .
+	 */
+	@NonNull
+	CompletionItem[] targets;
+}
+
+/**
+ * Arguments for 'completions' request.
+ */
+@JsonRpcData
+class CompletionsArguments {
+	/**
+	 * Returns completions in the scope of this stack frame. If not specified, the completions are returned for the
+	 * global scope.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer frameId;
+	/**
+	 * One or more source lines. Typically this is the text a user has typed into the debug console before he asked
+	 * for completion.
+	 */
+	@NonNull
+	String text;
+	/**
+	 * The character position for which to determine the completion proposals.
+	 */
+	int column;
+	/**
+	 * An optional line for which to determine the completion proposals. If missing the first line of the text is
+	 * assumed.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer line;
+}
+
+/**
+ * Response to 'exceptionInfo' request.
+ */
+@JsonRpcData
+class ExceptionInfoResponse {
+	/**
+	 * ID of the exception that was thrown.
+	 */
+	@NonNull
+	String exceptionId;
+	/**
+	 * Descriptive text for the exception provided by the debug adapter.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String description;
+	/**
+	 * Mode that caused the exception notification to be raised.
+	 */
+	@NonNull
+	ExceptionBreakMode breakMode;
+	/**
+	 * Detailed information about the exception.
+	 * <p>
+	 * This is an optional property.
+	 */
+	ExceptionDetails details;
+}
+
+/**
+ * Arguments for 'exceptionInfo' request.
+ */
+@JsonRpcData
+class ExceptionInfoArguments {
+	/**
+	 * Thread for which exception information should be retrieved.
+	 */
+	int threadId;
+}
+
+/**
+ * Response to 'readMemory' request.
+ */
+@JsonRpcData
+class ReadMemoryResponse {
+	/**
+	 * The address of the first byte of data returned.
+	 * <p>
+	 * Treated as a hex value if prefixed with '0x', or as a decimal value otherwise.
+	 */
+	@NonNull
+	String address;
+	/**
+	 * The number of unreadable bytes encountered after the last successfully read byte.
+	 * <p>
+	 * This can be used to determine the number of bytes that must be skipped before a subsequent 'readMemory' request
+	 * will succeed.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer unreadableBytes;
+	/**
+	 * The bytes read from memory, encoded using base64.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String data;
+}
+
+/**
+ * Arguments for 'readMemory' request.
+ */
+@JsonRpcData
+class ReadMemoryArguments {
+	/**
+	 * Memory reference to the base location from which data should be read.
+	 */
+	@NonNull
+	String memoryReference;
+	/**
+	 * Optional offset (in bytes) to be applied to the reference location before reading data. Can be negative.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer offset;
+	/**
+	 * Number of bytes to read at the specified location and offset.
+	 */
+	int count;
+}
+
+/**
+ * Response to 'disassemble' request.
+ */
+@JsonRpcData
+class DisassembleResponse {
+	/**
+	 * The list of disassembled instructions.
+	 */
+	@NonNull
+	DisassembledInstruction[] instructions;
+}
+
+/**
+ * Arguments for 'disassemble' request.
+ */
+@JsonRpcData
+class DisassembleArguments {
+	/**
+	 * Memory reference to the base location containing the instructions to disassemble.
+	 */
+	@NonNull
+	String memoryReference;
+	/**
+	 * Optional offset (in bytes) to be applied to the reference location before disassembling. Can be negative.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer offset;
+	/**
+	 * Optional offset (in instructions) to be applied after the byte offset (if any) before disassembling. Can be
+	 * negative.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer instructionOffset;
+	/**
+	 * Number of instructions to disassemble starting at the specified location and offset.
+	 * <p>
+	 * An adapter must return exactly this number of instructions - any unavailable instructions should be replaced
+	 * with an implementation-defined 'invalid instruction' value.
+	 */
+	int instructionCount;
+	/**
+	 * If true, the adapter should attempt to resolve memory addresses and other values to symbolic names.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean resolveSymbols;
+}
+
+/**
+ * Information about the capabilities of a debug adapter.
+ */
+@JsonRpcData
+class Capabilities {
+	/**
+	 * The debug adapter supports the 'configurationDone' request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsConfigurationDoneRequest;
+	/**
+	 * The debug adapter supports function breakpoints.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsFunctionBreakpoints;
+	/**
+	 * The debug adapter supports conditional breakpoints.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsConditionalBreakpoints;
+	/**
+	 * The debug adapter supports breakpoints that break execution after a specified number of hits.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsHitConditionalBreakpoints;
+	/**
+	 * The debug adapter supports a (side effect free) evaluate request for data hovers.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsEvaluateForHovers;
+	/**
+	 * Available exception filter options for the 'setExceptionBreakpoints' request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	ExceptionBreakpointsFilter[] exceptionBreakpointFilters;
+	/**
+	 * The debug adapter supports stepping back via the 'stepBack' and 'reverseContinue' requests.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsStepBack;
+	/**
+	 * The debug adapter supports setting a variable to a value.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsSetVariable;
+	/**
+	 * The debug adapter supports restarting a frame.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsRestartFrame;
+	/**
+	 * The debug adapter supports the 'gotoTargets' request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsGotoTargetsRequest;
+	/**
+	 * The debug adapter supports the 'stepInTargets' request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsStepInTargetsRequest;
+	/**
+	 * The debug adapter supports the 'completions' request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsCompletionsRequest;
+	/**
+	 * The set of characters that should trigger completion in a REPL. If not specified, the UI should assume the '.'
+	 * character.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String[] completionTriggerCharacters;
+	/**
+	 * The debug adapter supports the 'modules' request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsModulesRequest;
+	/**
+	 * The set of additional module information exposed by the debug adapter.
+	 * <p>
+	 * This is an optional property.
+	 */
+	ColumnDescriptor[] additionalModuleColumns;
+	/**
+	 * Checksum algorithms supported by the debug adapter.
+	 * <p>
+	 * This is an optional property.
+	 */
+	ChecksumAlgorithm[] supportedChecksumAlgorithms;
+	/**
+	 * The debug adapter supports the 'restart' request. In this case a client should not implement 'restart' by
+	 * terminating and relaunching the adapter but by calling the RestartRequest.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsRestartRequest;
+	/**
+	 * The debug adapter supports 'exceptionOptions' on the setExceptionBreakpoints request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsExceptionOptions;
+	/**
+	 * The debug adapter supports a 'format' attribute on the stackTraceRequest, variablesRequest, and
+	 * evaluateRequest.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsValueFormattingOptions;
+	/**
+	 * The debug adapter supports the 'exceptionInfo' request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsExceptionInfoRequest;
+	/**
+	 * The debug adapter supports the 'terminateDebuggee' attribute on the 'disconnect' request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportTerminateDebuggee;
+	/**
+	 * The debug adapter supports the delayed loading of parts of the stack, which requires that both the 'startFrame'
+	 * and 'levels' arguments and an optional 'totalFrames' result of the 'StackTrace' request are supported.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsDelayedStackTraceLoading;
+	/**
+	 * The debug adapter supports the 'loadedSources' request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsLoadedSourcesRequest;
+	/**
+	 * The debug adapter supports logpoints by interpreting the 'logMessage' attribute of the SourceBreakpoint.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsLogPoints;
+	/**
+	 * The debug adapter supports the 'terminateThreads' request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsTerminateThreadsRequest;
+	/**
+	 * The debug adapter supports the 'setExpression' request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsSetExpression;
+	/**
+	 * The debug adapter supports the 'terminate' request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsTerminateRequest;
+	/**
+	 * The debug adapter supports data breakpoints.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsDataBreakpoints;
+	/**
+	 * The debug adapter supports the 'readMemory' request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsReadMemoryRequest;
+	/**
+	 * The debug adapter supports the 'disassemble' request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsDisassembleRequest;
+	/**
+	 * The debug adapter supports the 'cancel' request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsCancelRequest;
+	/**
+	 * The debug adapter supports the 'breakpointLocations' request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsBreakpointLocationsRequest;
+	/**
+	 * The debug adapter supports the 'clipboard' context value in the 'evaluate' request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsClipboardContext;
+	/**
+	 * The debug adapter supports stepping granularities (argument 'granularity') for the stepping requests.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsSteppingGranularity;
+	/**
+	 * The debug adapter supports adding breakpoints based on instruction references.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsInstructionBreakpoints;
+	/**
+	 * The debug adapter supports 'filterOptions' as an argument on the 'setExceptionBreakpoints' request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsExceptionFilterOptions;
+}
+
+/**
+ * An ExceptionBreakpointsFilter is shown in the UI as an filter option for configuring how exceptions are dealt
+ * with.
+ */
+@JsonRpcData
+class ExceptionBreakpointsFilter {
+	/**
+	 * The internal ID of the filter option. This value is passed to the 'setExceptionBreakpoints' request.
+	 */
+	@NonNull
+	String filter;
+	/**
+	 * The name of the filter option. This will be shown in the UI.
+	 */
+	@NonNull
+	String label;
+	/**
+	 * Initial value of the filter option. If not specified a value 'false' is assumed.
+	 * <p>
+	 * This is an optional property.
+	 */
+	@SerializedName(value="default")
+	Boolean default_;
+	/**
+	 * Controls whether a condition can be specified for this filter option. If false or missing, a condition can not
+	 * be set.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean supportsCondition;
+}
+
+/**
+ * A structured message object. Used to return errors from requests.
+ */
+@JsonRpcData
+class Message {
+	/**
+	 * Unique identifier for the message.
+	 */
+	int id;
+	/**
+	 * A format string for the message. Embedded variables have the form '{name}'.
+	 * <p>
+	 * If variable name starts with an underscore character, the variable does not contain user data (PII) and can be
+	 * safely used for telemetry purposes.
+	 */
+	@NonNull
+	String format;
+	/**
+	 * An object used as a dictionary for looking up the variables in the format string.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Map<String, String> variables;
+	/**
+	 * If true send to telemetry.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean sendTelemetry;
+	/**
+	 * If true show user.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean showUser;
+	/**
+	 * An optional url where additional information about this message can be found.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String url;
+	/**
+	 * An optional label that is presented to the user as the UI for opening the url.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String urlLabel;
+}
+
+/**
+ * A Module object represents a row in the modules view.
+ * <p>
+ * Two attributes are mandatory: an id identifies a module in the modules view and is used in a ModuleEvent for
+ * identifying a module for adding, updating or deleting.
+ * <p>
+ * The name is used to minimally render the module in the UI.
+ * <p>
+
+ * <p>
+ * Additional attributes can be added to the module. They will show up in the module View if they have a
+ * corresponding ColumnDescriptor.
+ * <p>
+
+ * <p>
+ * To avoid an unnecessary proliferation of additional attributes with similar semantics but different names
+ * <p>
+ * we recommend to re-use attributes from the 'recommended' list below first, and only introduce new attributes if
+ * nothing appropriate could be found.
+ */
+@JsonRpcData
+class Module {
+	/**
+	 * Unique identifier for the module.
+	 */
+	@NonNull
+	Either<Integer, String> id;
+	/**
+	 * A name of the module.
+	 */
+	@NonNull
+	String name;
+	/**
+	 * optional but recommended attributes.
+	 * <p>
+	 * always try to use these first before introducing additional attributes.
+	 * <p>
+
+	 * <p>
+	 * Logical full path to the module. The exact definition is implementation defined, but usually this would be a
+	 * full path to the on-disk file for the module.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String path;
+	/**
+	 * True if the module is optimized.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean isOptimized;
+	/**
+	 * True if the module is considered 'user code' by a debugger that supports 'Just My Code'.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean isUserCode;
+	/**
+	 * Version of Module.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String version;
+	/**
+	 * User understandable description of if symbols were found for the module (ex: 'Symbols Loaded', 'Symbols not
+	 * found', etc.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String symbolStatus;
+	/**
+	 * Logical full path to the symbol file. The exact definition is implementation defined.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String symbolFilePath;
+	/**
+	 * Module created or modified.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String dateTimeStamp;
+	/**
+	 * Address range covered by this module.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String addressRange;
+}
+
+/**
+ * A ColumnDescriptor specifies what module attribute to show in a column of the ModulesView, how to format it,
+ * <p>
+ * and what the column's label should be.
+ * <p>
+ * It is only used if the underlying UI actually supports this level of customization.
+ */
+@JsonRpcData
+class ColumnDescriptor {
+	/**
+	 * Name of the attribute rendered in this column.
+	 */
+	@NonNull
+	String attributeName;
+	/**
+	 * Header UI label of column.
+	 */
+	@NonNull
+	String label;
+	/**
+	 * Format to use for the rendered values in this column. TBD how the format strings looks like.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String format;
+	/**
+	 * Datatype of values in this column.  Defaults to 'string' if not specified.
+	 * <p>
+	 * This is an optional property.
+	 */
+	ColumnDescriptorType type;
+	/**
+	 * Width of this column in characters (hint only).
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer width;
+}
+
+/**
+ * Datatype of values in this column.  Defaults to 'string' if not specified.
+ */
+enum ColumnDescriptorType {
+	STRING,
+	NUMBER,
+	BOOLEAN,
+	@SerializedName("unixTimestampUTC")
+	UNIX_TIMESTAMP_UTC
+}
+
+/**
+ * The ModulesViewDescriptor is the container for all declarative configuration options of a ModuleView.
+ * <p>
+ * For now it only specifies the columns to be shown in the modules view.
+ */
+@JsonRpcData
+class ModulesViewDescriptor {
+	/**
+
+	 */
+	@NonNull
+	ColumnDescriptor[] columns;
+}
+
+/**
+ * A Thread
+ */
+@JsonRpcData
+class Thread {
+	/**
+	 * Unique identifier for the thread.
+	 */
+	int id;
+	/**
+	 * A name of the thread.
+	 */
+	@NonNull
+	String name;
+}
+
+/**
+ * A Source is a descriptor for source code.
+ * <p>
+ * It is returned from the debug adapter as part of a StackFrame and it is used by clients when specifying
+ * breakpoints.
+ */
+@JsonRpcData
+class Source {
+	/**
+	 * The short name of the source. Every source returned from the debug adapter has a name.
+	 * <p>
+	 * When sending a source to the debug adapter this name is optional.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String name;
+	/**
+	 * The path of the source to be shown in the UI.
+	 * <p>
+	 * It is only used to locate and load the content of the source if no sourceReference is specified (or its value
+	 * is 0).
+	 * <p>
+	 * This is an optional property.
+	 */
+	String path;
+	/**
+	 * If sourceReference &gt; 0 the contents of the source must be retrieved through the SourceRequest (even if a
+	 * path is specified).
+	 * <p>
+	 * A sourceReference is only valid for a session, so it must not be used to persist a source.
+	 * <p>
+	 * The value should be less than or equal to 2147483647 (2^31-1).
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer sourceReference;
+	/**
+	 * An optional hint for how to present the source in the UI.
+	 * <p>
+	 * A value of 'deemphasize' can be used to indicate that the source is not available or that it is skipped on
+	 * stepping.
+	 * <p>
+	 * This is an optional property.
+	 */
+	SourcePresentationHint presentationHint;
+	/**
+	 * The (optional) origin of this source: possible values 'internal module', 'inlined content from source map',
+	 * etc.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String origin;
+	/**
+	 * An optional list of sources that are related to this source. These may be the source that generated this
+	 * source.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Source[] sources;
+	/**
+	 * Optional data that a debug adapter might want to loop through the client.
+	 * <p>
+	 * The client should leave the data intact and persist it across sessions. The client should not interpret the
+	 * data.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Object adapterData;
+	/**
+	 * The checksums associated with this file.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Checksum[] checksums;
+}
+
+/**
+ * An optional hint for how to present the source in the UI.
+ * <p>
+ * A value of 'deemphasize' can be used to indicate that the source is not available or that it is skipped on
+ * stepping.
+ */
+enum SourcePresentationHint {
+	NORMAL,
+	EMPHASIZE,
+	DEEMPHASIZE
+}
+
+/**
+ * A Stackframe contains the source location.
+ */
+@JsonRpcData
+class StackFrame {
+	/**
+	 * An identifier for the stack frame. It must be unique across all threads.
+	 * <p>
+	 * This id can be used to retrieve the scopes of the frame with the 'scopesRequest' or to restart the execution of
+	 * a stackframe.
+	 */
+	int id;
+	/**
+	 * The name of the stack frame, typically a method name.
+	 */
+	@NonNull
+	String name;
+	/**
+	 * The optional source of the frame.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Source source;
+	/**
+	 * The line within the file of the frame. If source is null or doesn't exist, line is 0 and must be ignored.
+	 */
+	int line;
+	/**
+	 * The column within the line. If source is null or doesn't exist, column is 0 and must be ignored.
+	 */
+	int column;
+	/**
+	 * An optional end line of the range covered by the stack frame.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer endLine;
+	/**
+	 * An optional end column of the range covered by the stack frame.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer endColumn;
+	/**
+	 * Optional memory reference for the current instruction pointer in this frame.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String instructionPointerReference;
+	/**
+	 * The module associated with this frame, if any.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Either<Integer, String> moduleId;
+	/**
+	 * An optional hint for how to present this frame in the UI.
+	 * <p>
+	 * A value of 'label' can be used to indicate that the frame is an artificial frame that is used as a visual label
+	 * or separator. A value of 'subtle' can be used to change the appearance of a frame in a 'subtle' way.
+	 * <p>
+	 * This is an optional property.
+	 */
+	StackFramePresentationHint presentationHint;
+}
+
+/**
+ * An optional hint for how to present this frame in the UI.
+ * <p>
+ * A value of 'label' can be used to indicate that the frame is an artificial frame that is used as a visual label
+ * or separator. A value of 'subtle' can be used to change the appearance of a frame in a 'subtle' way.
+ */
+enum StackFramePresentationHint {
+	NORMAL,
+	LABEL,
+	SUBTLE
+}
+
+/**
+ * A Scope is a named container for variables. Optionally a scope can map to a source or a range within a source.
+ */
+@JsonRpcData
+class Scope {
+	/**
+	 * Name of the scope such as 'Arguments', 'Locals', or 'Registers'. This string is shown in the UI as is and can
+	 * be translated.
+	 */
+	@NonNull
+	String name;
+	/**
+	 * An optional hint for how to present this scope in the UI. If this attribute is missing, the scope is shown with
+	 * a generic UI.
+	 * <p>
+	 * This is an optional property.
+	 * <p>
+	 * Possible values include - but not limited to those defined in {@link ScopePresentationHint}
+	 */
+	String presentationHint;
+	/**
+	 * The variables of this scope can be retrieved by passing the value of variablesReference to the
+	 * VariablesRequest.
+	 */
+	int variablesReference;
+	/**
+	 * The number of named variables in this scope.
+	 * <p>
+	 * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer namedVariables;
+	/**
+	 * The number of indexed variables in this scope.
+	 * <p>
+	 * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer indexedVariables;
+	/**
+	 * If true, the number of variables in this scope is large or expensive to retrieve.
+	 */
+	boolean expensive;
+	/**
+	 * Optional source for this scope.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Source source;
+	/**
+	 * Optional start line of the range covered by this scope.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer line;
+	/**
+	 * Optional start column of the range covered by this scope.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer column;
+	/**
+	 * Optional end line of the range covered by this scope.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer endLine;
+	/**
+	 * Optional end column of the range covered by this scope.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer endColumn;
+}
+
+/**
+ * An optional hint for how to present this scope in the UI. If this attribute is missing, the scope is shown with
+ * a generic UI.
+ * <p>
+ * Possible values include - but not limited to those defined in {@link ScopePresentationHint}
+ */
+interface ScopePresentationHint {
+	/**
+	 * Scope contains method arguments.
+	 */
+	public static final String ARGUMENTS = "arguments";
+	/**
+	 * Scope contains local variables.
+	 */
+	public static final String LOCALS = "locals";
+	/**
+	 * Scope contains registers. Only a single 'registers' scope should be returned from a 'scopes' request.
+	 */
+	public static final String REGISTERS = "registers";
+}
+
+/**
+ * A Variable is a name/value pair.
+ * <p>
+ * Optionally a variable can have a 'type' that is shown if space permits or when hovering over the variable's
+ * name.
+ * <p>
+ * An optional 'kind' is used to render additional properties of the variable, e.g. different icons can be used to
+ * indicate that a variable is public or private.
+ * <p>
+ * If the value is structured (has children), a handle is provided to retrieve the children with the
+ * VariablesRequest.
+ * <p>
+ * If the number of named or indexed children is large, the numbers should be returned via the optional
+ * 'namedVariables' and 'indexedVariables' attributes.
+ * <p>
+ * The client can use this optional information to present the children in a paged UI and fetch them in chunks.
+ */
+@JsonRpcData
+class Variable {
+	/**
+	 * The variable's name.
+	 */
+	@NonNull
+	String name;
+	/**
+	 * The variable's value. This can be a multi-line text, e.g. for a function the body of a function.
+	 */
+	@NonNull
+	String value;
+	/**
+	 * The type of the variable's value. Typically shown in the UI when hovering over the value.
+	 * <p>
+	 * This attribute should only be returned by a debug adapter if the client has passed the value true for the
+	 * 'supportsVariableType' capability of the 'initialize' request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String type;
+	/**
+	 * Properties of a variable that can be used to determine how to render the variable in the UI.
+	 * <p>
+	 * This is an optional property.
+	 */
+	VariablePresentationHint presentationHint;
+	/**
+	 * Optional evaluatable name of this variable which can be passed to the 'EvaluateRequest' to fetch the variable's
+	 * value.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String evaluateName;
+	/**
+	 * If variablesReference is &gt; 0, the variable is structured and its children can be retrieved by passing
+	 * variablesReference to the VariablesRequest.
+	 */
+	int variablesReference;
+	/**
+	 * The number of named child variables.
+	 * <p>
+	 * The client can use this optional information to present the children in a paged UI and fetch them in chunks.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer namedVariables;
+	/**
+	 * The number of indexed child variables.
+	 * <p>
+	 * The client can use this optional information to present the children in a paged UI and fetch them in chunks.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer indexedVariables;
+	/**
+	 * Optional memory reference for the variable if the variable represents executable code, such as a function
+	 * pointer.
+	 * <p>
+	 * This attribute is only required if the client has passed the value true for the 'supportsMemoryReferences'
+	 * capability of the 'initialize' request.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String memoryReference;
+}
+
+/**
+ * Optional properties of a variable that can be used to determine how to render the variable in the UI.
+ */
+@JsonRpcData
+class VariablePresentationHint {
+	/**
+	 * The kind of variable. Before introducing additional values, try to use the listed values.
+	 * <p>
+	 * This is an optional property.
+	 * <p>
+	 * Possible values include - but not limited to those defined in {@link VariablePresentationHintKind}
+	 */
+	String kind;
+	/**
+	 * Set of attributes represented as an array of strings. Before introducing additional values, try to use the
+	 * listed values.
+	 * <p>
+	 * This is an optional property.
+	 * <p>
+	 * Possible values include - but not limited to those defined in {@link VariablePresentationHintAttributes}
+	 */
+	String[] attributes;
+	/**
+	 * Visibility of variable. Before introducing additional values, try to use the listed values.
+	 * <p>
+	 * This is an optional property.
+	 * <p>
+	 * Possible values include - but not limited to those defined in {@link VariablePresentationHintVisibility}
+	 */
+	String visibility;
+}
+
+/**
+ * The kind of variable. Before introducing additional values, try to use the listed values.
+ * <p>
+ * Possible values include - but not limited to those defined in {@link VariablePresentationHintKind}
+ */
+interface VariablePresentationHintKind {
+	/**
+	 * Indicates that the object is a property.
+	 */
+	public static final String PROPERTY = "property";
+	/**
+	 * Indicates that the object is a method.
+	 */
+	public static final String METHOD = "method";
+	/**
+	 * Indicates that the object is a class.
+	 */
+	public static final String CLASS = "class";
+	/**
+	 * Indicates that the object is data.
+	 */
+	public static final String DATA = "data";
+	/**
+	 * Indicates that the object is an event.
+	 */
+	public static final String EVENT = "event";
+	/**
+	 * Indicates that the object is a base class.
+	 */
+	public static final String BASE_CLASS = "baseClass";
+	/**
+	 * Indicates that the object is an inner class.
+	 */
+	public static final String INNER_CLASS = "innerClass";
+	/**
+	 * Indicates that the object is an interface.
+	 */
+	public static final String INTERFACE = "interface";
+	/**
+	 * Indicates that the object is the most derived class.
+	 */
+	public static final String MOST_DERIVED_CLASS = "mostDerivedClass";
+	/**
+	 * Indicates that the object is virtual, that means it is a synthetic object introducedby the
+	 * adapter for
+	 * rendering purposes, e.g. an index range for large arrays.
+	 */
+	public static final String VIRTUAL = "virtual";
+	/**
+	 * Deprecated: Indicates that a data breakpoint is registered for the object. The 'hasDataBreakpoint' attribute
+	 * should generally be used instead.
+	 * <p>
+	 * @deprecated The 'hasDataBreakpoint' attribute should generally be used instead.
+	 */
+	@Deprecated
+	public static final String DATA_BREAKPOINT = "dataBreakpoint";
+}
+
+/**
+
+ * <p>
+ * Possible values include - but not limited to those defined in {@link VariablePresentationHintAttributes}
+ */
+interface VariablePresentationHintAttributes {
+	/**
+	 * Indicates that the object is static.
+	 */
+	public static final String STATIC = "static";
+	/**
+	 * Indicates that the object is a constant.
+	 */
+	public static final String CONSTANT = "constant";
+	/**
+	 * Indicates that the object is read only.
+	 */
+	public static final String READ_ONLY = "readOnly";
+	/**
+	 * Indicates that the object is a raw string.
+	 */
+	public static final String RAW_STRING = "rawString";
+	/**
+	 * Indicates that the object can have an Object ID created for it.
+	 */
+	public static final String HAS_OBJECT_ID = "hasObjectId";
+	/**
+	 * Indicates that the object has an Object ID associated with it.
+	 */
+	public static final String CAN_HAVE_OBJECT_ID = "canHaveObjectId";
+	/**
+	 * Indicates that the evaluation had side effects.
+	 */
+	public static final String HAS_SIDE_EFFECTS = "hasSideEffects";
+	/**
+	 * Indicates that the object has its value tracked by a data breakpoint.
+	 */
+	public static final String HAS_DATA_BREAKPOINT = "hasDataBreakpoint";
+}
+
+/**
+ * Visibility of variable. Before introducing additional values, try to use the listed values.
+ * <p>
+ * Possible values include - but not limited to those defined in {@link VariablePresentationHintVisibility}
+ */
+interface VariablePresentationHintVisibility {
+	public static final String PUBLIC = "public";
+	public static final String PRIVATE = "private";
+	public static final String PROTECTED = "protected";
+	public static final String INTERNAL = "internal";
+	public static final String FINAL = "final";
+}
+
+/**
+ * Properties of a breakpoint location returned from the 'breakpointLocations' request.
+ */
+@JsonRpcData
+class BreakpointLocation {
+	/**
+	 * Start line of breakpoint location.
+	 */
+	int line;
+	/**
+	 * Optional start column of breakpoint location.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer column;
+	/**
+	 * Optional end line of breakpoint location if the location covers a range.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer endLine;
+	/**
+	 * Optional end column of breakpoint location if the location covers a range.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer endColumn;
+}
+
+/**
+ * Properties of a breakpoint or logpoint passed to the setBreakpoints request.
+ */
+@JsonRpcData
+class SourceBreakpoint {
+	/**
+	 * The source line of the breakpoint or logpoint.
+	 */
+	int line;
+	/**
+	 * An optional source column of the breakpoint.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer column;
+	/**
+	 * An optional expression for conditional breakpoints.
+	 * <p>
+	 * It is only honored by a debug adapter if the capability 'supportsConditionalBreakpoints' is true.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String condition;
+	/**
+	 * An optional expression that controls how many hits of the breakpoint are ignored.
+	 * <p>
+	 * The backend is expected to interpret the expression as needed.
+	 * <p>
+	 * The attribute is only honored by a debug adapter if the capability 'supportsHitConditionalBreakpoints' is true.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String hitCondition;
+	/**
+	 * If this attribute exists and is non-empty, the backend must not 'break' (stop)
+	 * <p>
+	 * but log the message instead. Expressions within {} are interpolated.
+	 * <p>
+	 * The attribute is only honored by a debug adapter if the capability 'supportsLogPoints' is true.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String logMessage;
+}
+
+/**
+ * Properties of a breakpoint passed to the setFunctionBreakpoints request.
+ */
+@JsonRpcData
+class FunctionBreakpoint {
+	/**
+	 * The name of the function.
+	 */
+	@NonNull
+	String name;
+	/**
+	 * An optional expression for conditional breakpoints.
+	 * <p>
+	 * It is only honored by a debug adapter if the capability 'supportsConditionalBreakpoints' is true.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String condition;
+	/**
+	 * An optional expression that controls how many hits of the breakpoint are ignored.
+	 * <p>
+	 * The backend is expected to interpret the expression as needed.
+	 * <p>
+	 * The attribute is only honored by a debug adapter if the capability 'supportsHitConditionalBreakpoints' is true.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String hitCondition;
+}
+
+/**
+ * This enumeration defines all possible access types for data breakpoints.
+ */
+enum DataBreakpointAccessType {
+	READ,
+	WRITE,
+	READ_WRITE
+}
+
+/**
+ * Properties of a data breakpoint passed to the setDataBreakpoints request.
+ */
+@JsonRpcData
+class DataBreakpoint {
+	/**
+	 * An id representing the data. This id is returned from the dataBreakpointInfo request.
+	 */
+	@NonNull
+	String dataId;
+	/**
+	 * The access type of the data.
+	 * <p>
+	 * This is an optional property.
+	 */
+	DataBreakpointAccessType accessType;
+	/**
+	 * An optional expression for conditional breakpoints.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String condition;
+	/**
+	 * An optional expression that controls how many hits of the breakpoint are ignored.
+	 * <p>
+	 * The backend is expected to interpret the expression as needed.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String hitCondition;
+}
+
+/**
+ * Properties of a breakpoint passed to the setInstructionBreakpoints request
+ */
+@JsonRpcData
+class InstructionBreakpoint {
+	/**
+	 * The instruction reference of the breakpoint.
+	 * <p>
+	 * This should be a memory or instruction pointer reference from an EvaluateResponse, Variable, StackFrame,
+	 * GotoTarget, or Breakpoint.
+	 */
+	@NonNull
+	String instructionReference;
+	/**
+	 * An optional offset from the instruction reference.
+	 * <p>
+	 * This can be negative.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer offset;
+	/**
+	 * An optional expression for conditional breakpoints.
+	 * <p>
+	 * It is only honored by a debug adapter if the capability 'supportsConditionalBreakpoints' is true.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String condition;
+	/**
+	 * An optional expression that controls how many hits of the breakpoint are ignored.
+	 * <p>
+	 * The backend is expected to interpret the expression as needed.
+	 * <p>
+	 * The attribute is only honored by a debug adapter if the capability 'supportsHitConditionalBreakpoints' is true.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String hitCondition;
+}
+
+/**
+ * Information about a Breakpoint created in setBreakpoints, setFunctionBreakpoints, setInstructionBreakpoints, or
+ * setDataBreakpoints.
+ */
+@JsonRpcData
+class Breakpoint {
+	/**
+	 * An optional identifier for the breakpoint. It is needed if breakpoint events are used to update or remove
+	 * breakpoints.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer id;
+	/**
+	 * If true breakpoint could be set (but not necessarily at the desired location).
+	 */
+	boolean verified;
+	/**
+	 * An optional message about the state of the breakpoint.
+	 * <p>
+	 * This is shown to the user and can be used to explain why a breakpoint could not be verified.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String message;
+	/**
+	 * The source where the breakpoint is located.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Source source;
+	/**
+	 * The start line of the actual range covered by the breakpoint.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer line;
+	/**
+	 * An optional start column of the actual range covered by the breakpoint.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer column;
+	/**
+	 * An optional end line of the actual range covered by the breakpoint.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer endLine;
+	/**
+	 * An optional end column of the actual range covered by the breakpoint.
+	 * <p>
+	 * If no end line is given, then the end column is assumed to be in the start line.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer endColumn;
+	/**
+	 * An optional memory reference to where the breakpoint is set.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String instructionReference;
+	/**
+	 * An optional offset from the instruction reference.
+	 * <p>
+	 * This can be negative.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer offset;
+}
+
+/**
+ * The granularity of one 'step' in the stepping requests 'next', 'stepIn', 'stepOut', and 'stepBack'.
+ */
+enum SteppingGranularity {
+	/**
+	 * The step should allow the program to run until the current statement has finished executing.
+	 * The meaning of a
+	 * statement is determined by the adapter and it may be considered equivalent to a line.
+	 * For example 'for(int i =
+	 * 0; i &lt; 10; i++) could be considered to have 3 statements 'int i = 0', 'i &lt; 10', and 'i++'.
+	 */
+	STATEMENT,
+	/**
+	 * The step should allow the program to run until the current source line has executed.
+	 */
+	LINE,
+	/**
+	 * The step should allow one instruction to execute (e.g. one x86 instruction).
+	 */
+	INSTRUCTION
+}
+
+/**
+ * A StepInTarget can be used in the 'stepIn' request and determines into which single target the stepIn request
+ * should step.
+ */
+@JsonRpcData
+class StepInTarget {
+	/**
+	 * Unique identifier for a stepIn target.
+	 */
+	int id;
+	/**
+	 * The name of the stepIn target (shown in the UI).
+	 */
+	@NonNull
+	String label;
+}
+
+/**
+ * A GotoTarget describes a code location that can be used as a target in the 'goto' request.
+ * <p>
+ * The possible goto targets can be determined via the 'gotoTargets' request.
+ */
+@JsonRpcData
+class GotoTarget {
+	/**
+	 * Unique identifier for a goto target. This is used in the goto request.
+	 */
+	int id;
+	/**
+	 * The name of the goto target (shown in the UI).
+	 */
+	@NonNull
+	String label;
+	/**
+	 * The line of the goto target.
+	 */
+	int line;
+	/**
+	 * An optional column of the goto target.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer column;
+	/**
+	 * An optional end line of the range covered by the goto target.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer endLine;
+	/**
+	 * An optional end column of the range covered by the goto target.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer endColumn;
+	/**
+	 * Optional memory reference for the instruction pointer value represented by this target.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String instructionPointerReference;
+}
+
+/**
+ * CompletionItems are the suggestions returned from the CompletionsRequest.
+ */
+@JsonRpcData
+class CompletionItem {
+	/**
+	 * The label of this completion item. By default this is also the text that is inserted when selecting this
+	 * completion.
+	 */
+	@NonNull
+	String label;
+	/**
+	 * If text is not falsy then it is inserted instead of the label.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String text;
+	/**
+	 * A string that should be used when comparing this item with other items. When `falsy` the label is used.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String sortText;
+	/**
+	 * The item's type. Typically the client uses this information to render the item in the UI with an icon.
+	 * <p>
+	 * This is an optional property.
+	 */
+	CompletionItemType type;
+	/**
+	 * This value determines the location (in the CompletionsRequest's 'text' attribute) where the completion text is
+	 * added.
+	 * <p>
+	 * If missing the text is added at the location specified by the CompletionsRequest's 'column' attribute.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer start;
+	/**
+	 * This value determines how many characters are overwritten by the completion text.
+	 * <p>
+	 * If missing the value 0 is assumed which results in the completion text being inserted.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer length;
+	/**
+	 * Determines the start of the new selection after the text has been inserted (or replaced).
+	 * <p>
+	 * The start position must in the range 0 and length of the completion text.
+	 * <p>
+	 * If omitted the selection starts at the end of the completion text.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer selectionStart;
+	/**
+	 * Determines the length of the new selection after the text has been inserted (or replaced).
+	 * <p>
+	 * The selection can not extend beyond the bounds of the completion text.
+	 * <p>
+	 * If omitted the length is assumed to be 0.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer selectionLength;
+}
+
+/**
+ * Some predefined types for the CompletionItem. Please note that not all clients have specific icons for all of
+ * them.
+ */
+enum CompletionItemType {
+	METHOD,
+	FUNCTION,
+	CONSTRUCTOR,
+	FIELD,
+	VARIABLE,
+	CLASS,
+	INTERFACE,
+	MODULE,
+	PROPERTY,
+	UNIT,
+	VALUE,
+	ENUM,
+	KEYWORD,
+	SNIPPET,
+	TEXT,
+	COLOR,
+	FILE,
+	REFERENCE,
+	CUSTOMCOLOR
+}
+
+/**
+ * Names of checksum algorithms that may be supported by a debug adapter.
+ */
+enum ChecksumAlgorithm {
+	@SerializedName("MD5")
+	MD5,
+	@SerializedName("SHA1")
+	SHA1,
+	@SerializedName("SHA256")
+	SHA256,
+	TIMESTAMP
+}
+
+/**
+ * The checksum of an item calculated by the specified algorithm.
+ */
+@JsonRpcData
+class Checksum {
+	/**
+	 * The algorithm used to calculate this checksum.
+	 */
+	@NonNull
+	ChecksumAlgorithm algorithm;
+	/**
+	 * Value of the checksum.
+	 */
+	@NonNull
+	String checksum;
+}
+
+/**
+ * Provides formatting information for a value.
+ */
+@JsonRpcData
+class ValueFormat {
+	/**
+	 * Display the value in hex.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean hex;
+}
+
+/**
+ * Provides formatting information for a stack frame.
+ */
+@JsonRpcData
+class StackFrameFormat extends ValueFormat {
+	/**
+	 * Displays parameters for the stack frame.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean parameters;
+	/**
+	 * Displays the types of parameters for the stack frame.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean parameterTypes;
+	/**
+	 * Displays the names of parameters for the stack frame.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean parameterNames;
+	/**
+	 * Displays the values of parameters for the stack frame.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean parameterValues;
+	/**
+	 * Displays the line number of the stack frame.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean line;
+	/**
+	 * Displays the module of the stack frame.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean module;
+	/**
+	 * Includes all stack frames, including those the debug adapter might otherwise hide.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean includeAll;
+}
+
+/**
+ * An ExceptionFilterOptions is used to specify an exception filter together with a condition for the
+ * setExceptionsFilter request.
+ */
+@JsonRpcData
+class ExceptionFilterOptions {
+	/**
+	 * ID of an exception filter returned by the 'exceptionBreakpointFilters' capability.
+	 */
+	@NonNull
+	String filterId;
+	/**
+	 * An optional expression for conditional exceptions.
+	 * <p>
+	 * The exception will break into the debugger if the result of the condition is true.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String condition;
+}
+
+/**
+ * An ExceptionOptions assigns configuration options to a set of exceptions.
+ */
+@JsonRpcData
+class ExceptionOptions {
+	/**
+	 * A path that selects a single or multiple exceptions in a tree. If 'path' is missing, the whole tree is
+	 * selected.
+	 * <p>
+	 * By convention the first segment of the path is a category that is used to group exceptions in the UI.
+	 * <p>
+	 * This is an optional property.
+	 */
+	ExceptionPathSegment[] path;
+	/**
+	 * Condition when a thrown exception should result in a break.
+	 */
+	@NonNull
+	ExceptionBreakMode breakMode;
+}
+
+/**
+ * This enumeration defines all possible conditions when a thrown exception should result in a break.
+ * <p>
+ * never: never breaks,
+ * <p>
+ * always: always breaks,
+ * <p>
+ * unhandled: breaks when exception unhandled,
+ * <p>
+ * userUnhandled: breaks if the exception is not handled by user code.
+ */
+enum ExceptionBreakMode {
+	NEVER,
+	ALWAYS,
+	UNHANDLED,
+	USER_UNHANDLED
+}
+
+/**
+ * An ExceptionPathSegment represents a segment in a path that is used to match leafs or nodes in a tree of
+ * exceptions.
+ * <p>
+ * If a segment consists of more than one name, it matches the names provided if 'negate' is false or missing or
+ * <p>
+ * it matches anything except the names provided if 'negate' is true.
+ */
+@JsonRpcData
+class ExceptionPathSegment {
+	/**
+	 * If false or missing this segment matches the names provided, otherwise it matches anything except the names
+	 * provided.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Boolean negate;
+	/**
+	 * Depending on the value of 'negate' the names that should match or not match.
+	 */
+	@NonNull
+	String[] names;
+}
+
+/**
+ * Detailed information about an exception that has occurred.
+ */
+@JsonRpcData
+class ExceptionDetails {
+	/**
+	 * Message contained in the exception.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String message;
+	/**
+	 * Short type name of the exception object.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String typeName;
+	/**
+	 * Fully-qualified type name of the exception object.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String fullTypeName;
+	/**
+	 * Optional expression that can be evaluated in the current scope to obtain the exception object.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String evaluateName;
+	/**
+	 * Stack trace at the time the exception was thrown.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String stackTrace;
+	/**
+	 * Details of the exception contained by this exception, if any.
+	 * <p>
+	 * This is an optional property.
+	 */
+	ExceptionDetails[] innerException;
+}
+
+/**
+ * Represents a single disassembled instruction.
+ */
+@JsonRpcData
+class DisassembledInstruction {
+	/**
+	 * The address of the instruction. Treated as a hex value if prefixed with '0x', or as a decimal value otherwise.
+	 */
+	@NonNull
+	String address;
+	/**
+	 * Optional raw bytes representing the instruction and its operands, in an implementation-defined format.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String instructionBytes;
+	/**
+	 * Text representing the instruction and its operands, in an implementation-defined format.
+	 */
+	@NonNull
+	String instruction;
+	/**
+	 * Name of the symbol that corresponds with the location of this instruction, if any.
+	 * <p>
+	 * This is an optional property.
+	 */
+	String symbol;
+	/**
+	 * Source location that corresponds to this instruction, if any.
+	 * <p>
+	 * Should always be set (if available) on the first instruction returned,
+	 * <p>
+	 * but can be omitted afterwards if this instruction maps to the same source file as the previous instruction.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Source location;
+	/**
+	 * The line within the source location that corresponds to this instruction, if any.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer line;
+	/**
+	 * The column within the line that corresponds to this instruction, if any.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer column;
+	/**
+	 * The end line of the range that corresponds to this instruction, if any.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer endLine;
+	/**
+	 * The end column of the range that corresponds to this instruction, if any.
+	 * <p>
+	 * This is an optional property.
+	 */
+	Integer endColumn;
+}
+
+/**
+ * Logical areas that can be invalidated by the 'invalidated' event.
+ * <p>
+ * Possible values include - but not limited to those defined in {@link InvalidatedAreas}
+ */
+interface InvalidatedAreas {
+	/**
+	 * All previously fetched data has become invalid and needs to be refetched.
+	 */
+	public static final String ALL = "all";
+	/**
+	 * Previously fetched stack related data has become invalid and needs to be refetched.
+	 */
+	public static final String STACKS = "stacks";
+	/**
+	 * Previously fetched thread related data has become invalid and needs to be refetched.
+	 */
+	public static final String THREADS = "threads";
+	/**
+	 * Previously fetched variable data has become invalid and needs to be refetched.
+	 */
+	public static final String VARIABLES = "variables";
+}
diff --git a/java/org/eclipse/lsp4j/debug/DisassembleArguments.java b/java/org/eclipse/lsp4j/debug/DisassembleArguments.java
new file mode 100644
index 0000000..1d0ab81
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/DisassembleArguments.java
@@ -0,0 +1,214 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'disassemble' request.
+ */
+@SuppressWarnings("all")
+public class DisassembleArguments {
+  /**
+   * Memory reference to the base location containing the instructions to disassemble.
+   */
+  @NonNull
+  private String memoryReference;
+  
+  /**
+   * Optional offset (in bytes) to be applied to the reference location before disassembling. Can be negative.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer offset;
+  
+  /**
+   * Optional offset (in instructions) to be applied after the byte offset (if any) before disassembling. Can be
+   * negative.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer instructionOffset;
+  
+  /**
+   * Number of instructions to disassemble starting at the specified location and offset.
+   * <p>
+   * An adapter must return exactly this number of instructions - any unavailable instructions should be replaced
+   * with an implementation-defined 'invalid instruction' value.
+   */
+  private int instructionCount;
+  
+  /**
+   * If true, the adapter should attempt to resolve memory addresses and other values to symbolic names.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean resolveSymbols;
+  
+  /**
+   * Memory reference to the base location containing the instructions to disassemble.
+   */
+  @Pure
+  @NonNull
+  public String getMemoryReference() {
+    return this.memoryReference;
+  }
+  
+  /**
+   * Memory reference to the base location containing the instructions to disassemble.
+   */
+  public void setMemoryReference(@NonNull final String memoryReference) {
+    this.memoryReference = Preconditions.checkNotNull(memoryReference, "memoryReference");
+  }
+  
+  /**
+   * Optional offset (in bytes) to be applied to the reference location before disassembling. Can be negative.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getOffset() {
+    return this.offset;
+  }
+  
+  /**
+   * Optional offset (in bytes) to be applied to the reference location before disassembling. Can be negative.
+   * <p>
+   * This is an optional property.
+   */
+  public void setOffset(final Integer offset) {
+    this.offset = offset;
+  }
+  
+  /**
+   * Optional offset (in instructions) to be applied after the byte offset (if any) before disassembling. Can be
+   * negative.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getInstructionOffset() {
+    return this.instructionOffset;
+  }
+  
+  /**
+   * Optional offset (in instructions) to be applied after the byte offset (if any) before disassembling. Can be
+   * negative.
+   * <p>
+   * This is an optional property.
+   */
+  public void setInstructionOffset(final Integer instructionOffset) {
+    this.instructionOffset = instructionOffset;
+  }
+  
+  /**
+   * Number of instructions to disassemble starting at the specified location and offset.
+   * <p>
+   * An adapter must return exactly this number of instructions - any unavailable instructions should be replaced
+   * with an implementation-defined 'invalid instruction' value.
+   */
+  @Pure
+  public int getInstructionCount() {
+    return this.instructionCount;
+  }
+  
+  /**
+   * Number of instructions to disassemble starting at the specified location and offset.
+   * <p>
+   * An adapter must return exactly this number of instructions - any unavailable instructions should be replaced
+   * with an implementation-defined 'invalid instruction' value.
+   */
+  public void setInstructionCount(final int instructionCount) {
+    this.instructionCount = instructionCount;
+  }
+  
+  /**
+   * If true, the adapter should attempt to resolve memory addresses and other values to symbolic names.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getResolveSymbols() {
+    return this.resolveSymbols;
+  }
+  
+  /**
+   * If true, the adapter should attempt to resolve memory addresses and other values to symbolic names.
+   * <p>
+   * This is an optional property.
+   */
+  public void setResolveSymbols(final Boolean resolveSymbols) {
+    this.resolveSymbols = resolveSymbols;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("memoryReference", this.memoryReference);
+    b.add("offset", this.offset);
+    b.add("instructionOffset", this.instructionOffset);
+    b.add("instructionCount", this.instructionCount);
+    b.add("resolveSymbols", this.resolveSymbols);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DisassembleArguments other = (DisassembleArguments) obj;
+    if (this.memoryReference == null) {
+      if (other.memoryReference != null)
+        return false;
+    } else if (!this.memoryReference.equals(other.memoryReference))
+      return false;
+    if (this.offset == null) {
+      if (other.offset != null)
+        return false;
+    } else if (!this.offset.equals(other.offset))
+      return false;
+    if (this.instructionOffset == null) {
+      if (other.instructionOffset != null)
+        return false;
+    } else if (!this.instructionOffset.equals(other.instructionOffset))
+      return false;
+    if (other.instructionCount != this.instructionCount)
+      return false;
+    if (this.resolveSymbols == null) {
+      if (other.resolveSymbols != null)
+        return false;
+    } else if (!this.resolveSymbols.equals(other.resolveSymbols))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.memoryReference== null) ? 0 : this.memoryReference.hashCode());
+    result = prime * result + ((this.offset== null) ? 0 : this.offset.hashCode());
+    result = prime * result + ((this.instructionOffset== null) ? 0 : this.instructionOffset.hashCode());
+    result = prime * result + this.instructionCount;
+    return prime * result + ((this.resolveSymbols== null) ? 0 : this.resolveSymbols.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/DisassembleResponse.java b/java/org/eclipse/lsp4j/debug/DisassembleResponse.java
new file mode 100644
index 0000000..2798c94
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/DisassembleResponse.java
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.lsp4j.debug.DisassembledInstruction;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Response to 'disassemble' request.
+ */
+@SuppressWarnings("all")
+public class DisassembleResponse {
+  /**
+   * The list of disassembled instructions.
+   */
+  @NonNull
+  private DisassembledInstruction[] instructions;
+  
+  /**
+   * The list of disassembled instructions.
+   */
+  @Pure
+  @NonNull
+  public DisassembledInstruction[] getInstructions() {
+    return this.instructions;
+  }
+  
+  /**
+   * The list of disassembled instructions.
+   */
+  public void setInstructions(@NonNull final DisassembledInstruction[] instructions) {
+    this.instructions = Preconditions.checkNotNull(instructions, "instructions");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("instructions", this.instructions);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DisassembleResponse other = (DisassembleResponse) obj;
+    if (this.instructions == null) {
+      if (other.instructions != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.instructions, other.instructions))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.instructions== null) ? 0 : Arrays.deepHashCode(this.instructions));
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/DisassembledInstruction.java b/java/org/eclipse/lsp4j/debug/DisassembledInstruction.java
new file mode 100644
index 0000000..ffc74ae
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/DisassembledInstruction.java
@@ -0,0 +1,352 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.Source;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Represents a single disassembled instruction.
+ */
+@SuppressWarnings("all")
+public class DisassembledInstruction {
+  /**
+   * The address of the instruction. Treated as a hex value if prefixed with '0x', or as a decimal value otherwise.
+   */
+  @NonNull
+  private String address;
+  
+  /**
+   * Optional raw bytes representing the instruction and its operands, in an implementation-defined format.
+   * <p>
+   * This is an optional property.
+   */
+  private String instructionBytes;
+  
+  /**
+   * Text representing the instruction and its operands, in an implementation-defined format.
+   */
+  @NonNull
+  private String instruction;
+  
+  /**
+   * Name of the symbol that corresponds with the location of this instruction, if any.
+   * <p>
+   * This is an optional property.
+   */
+  private String symbol;
+  
+  /**
+   * Source location that corresponds to this instruction, if any.
+   * <p>
+   * Should always be set (if available) on the first instruction returned,
+   * <p>
+   * but can be omitted afterwards if this instruction maps to the same source file as the previous instruction.
+   * <p>
+   * This is an optional property.
+   */
+  private Source location;
+  
+  /**
+   * The line within the source location that corresponds to this instruction, if any.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer line;
+  
+  /**
+   * The column within the line that corresponds to this instruction, if any.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer column;
+  
+  /**
+   * The end line of the range that corresponds to this instruction, if any.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer endLine;
+  
+  /**
+   * The end column of the range that corresponds to this instruction, if any.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer endColumn;
+  
+  /**
+   * The address of the instruction. Treated as a hex value if prefixed with '0x', or as a decimal value otherwise.
+   */
+  @Pure
+  @NonNull
+  public String getAddress() {
+    return this.address;
+  }
+  
+  /**
+   * The address of the instruction. Treated as a hex value if prefixed with '0x', or as a decimal value otherwise.
+   */
+  public void setAddress(@NonNull final String address) {
+    this.address = Preconditions.checkNotNull(address, "address");
+  }
+  
+  /**
+   * Optional raw bytes representing the instruction and its operands, in an implementation-defined format.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getInstructionBytes() {
+    return this.instructionBytes;
+  }
+  
+  /**
+   * Optional raw bytes representing the instruction and its operands, in an implementation-defined format.
+   * <p>
+   * This is an optional property.
+   */
+  public void setInstructionBytes(final String instructionBytes) {
+    this.instructionBytes = instructionBytes;
+  }
+  
+  /**
+   * Text representing the instruction and its operands, in an implementation-defined format.
+   */
+  @Pure
+  @NonNull
+  public String getInstruction() {
+    return this.instruction;
+  }
+  
+  /**
+   * Text representing the instruction and its operands, in an implementation-defined format.
+   */
+  public void setInstruction(@NonNull final String instruction) {
+    this.instruction = Preconditions.checkNotNull(instruction, "instruction");
+  }
+  
+  /**
+   * Name of the symbol that corresponds with the location of this instruction, if any.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getSymbol() {
+    return this.symbol;
+  }
+  
+  /**
+   * Name of the symbol that corresponds with the location of this instruction, if any.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSymbol(final String symbol) {
+    this.symbol = symbol;
+  }
+  
+  /**
+   * Source location that corresponds to this instruction, if any.
+   * <p>
+   * Should always be set (if available) on the first instruction returned,
+   * <p>
+   * but can be omitted afterwards if this instruction maps to the same source file as the previous instruction.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Source getLocation() {
+    return this.location;
+  }
+  
+  /**
+   * Source location that corresponds to this instruction, if any.
+   * <p>
+   * Should always be set (if available) on the first instruction returned,
+   * <p>
+   * but can be omitted afterwards if this instruction maps to the same source file as the previous instruction.
+   * <p>
+   * This is an optional property.
+   */
+  public void setLocation(final Source location) {
+    this.location = location;
+  }
+  
+  /**
+   * The line within the source location that corresponds to this instruction, if any.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getLine() {
+    return this.line;
+  }
+  
+  /**
+   * The line within the source location that corresponds to this instruction, if any.
+   * <p>
+   * This is an optional property.
+   */
+  public void setLine(final Integer line) {
+    this.line = line;
+  }
+  
+  /**
+   * The column within the line that corresponds to this instruction, if any.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getColumn() {
+    return this.column;
+  }
+  
+  /**
+   * The column within the line that corresponds to this instruction, if any.
+   * <p>
+   * This is an optional property.
+   */
+  public void setColumn(final Integer column) {
+    this.column = column;
+  }
+  
+  /**
+   * The end line of the range that corresponds to this instruction, if any.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getEndLine() {
+    return this.endLine;
+  }
+  
+  /**
+   * The end line of the range that corresponds to this instruction, if any.
+   * <p>
+   * This is an optional property.
+   */
+  public void setEndLine(final Integer endLine) {
+    this.endLine = endLine;
+  }
+  
+  /**
+   * The end column of the range that corresponds to this instruction, if any.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getEndColumn() {
+    return this.endColumn;
+  }
+  
+  /**
+   * The end column of the range that corresponds to this instruction, if any.
+   * <p>
+   * This is an optional property.
+   */
+  public void setEndColumn(final Integer endColumn) {
+    this.endColumn = endColumn;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("address", this.address);
+    b.add("instructionBytes", this.instructionBytes);
+    b.add("instruction", this.instruction);
+    b.add("symbol", this.symbol);
+    b.add("location", this.location);
+    b.add("line", this.line);
+    b.add("column", this.column);
+    b.add("endLine", this.endLine);
+    b.add("endColumn", this.endColumn);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DisassembledInstruction other = (DisassembledInstruction) obj;
+    if (this.address == null) {
+      if (other.address != null)
+        return false;
+    } else if (!this.address.equals(other.address))
+      return false;
+    if (this.instructionBytes == null) {
+      if (other.instructionBytes != null)
+        return false;
+    } else if (!this.instructionBytes.equals(other.instructionBytes))
+      return false;
+    if (this.instruction == null) {
+      if (other.instruction != null)
+        return false;
+    } else if (!this.instruction.equals(other.instruction))
+      return false;
+    if (this.symbol == null) {
+      if (other.symbol != null)
+        return false;
+    } else if (!this.symbol.equals(other.symbol))
+      return false;
+    if (this.location == null) {
+      if (other.location != null)
+        return false;
+    } else if (!this.location.equals(other.location))
+      return false;
+    if (this.line == null) {
+      if (other.line != null)
+        return false;
+    } else if (!this.line.equals(other.line))
+      return false;
+    if (this.column == null) {
+      if (other.column != null)
+        return false;
+    } else if (!this.column.equals(other.column))
+      return false;
+    if (this.endLine == null) {
+      if (other.endLine != null)
+        return false;
+    } else if (!this.endLine.equals(other.endLine))
+      return false;
+    if (this.endColumn == null) {
+      if (other.endColumn != null)
+        return false;
+    } else if (!this.endColumn.equals(other.endColumn))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.address== null) ? 0 : this.address.hashCode());
+    result = prime * result + ((this.instructionBytes== null) ? 0 : this.instructionBytes.hashCode());
+    result = prime * result + ((this.instruction== null) ? 0 : this.instruction.hashCode());
+    result = prime * result + ((this.symbol== null) ? 0 : this.symbol.hashCode());
+    result = prime * result + ((this.location== null) ? 0 : this.location.hashCode());
+    result = prime * result + ((this.line== null) ? 0 : this.line.hashCode());
+    result = prime * result + ((this.column== null) ? 0 : this.column.hashCode());
+    result = prime * result + ((this.endLine== null) ? 0 : this.endLine.hashCode());
+    return prime * result + ((this.endColumn== null) ? 0 : this.endColumn.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/DisconnectArguments.java b/java/org/eclipse/lsp4j/debug/DisconnectArguments.java
new file mode 100644
index 0000000..2f64405
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/DisconnectArguments.java
@@ -0,0 +1,126 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'disconnect' request.
+ */
+@SuppressWarnings("all")
+public class DisconnectArguments {
+  /**
+   * A value of true indicates that this 'disconnect' request is part of a restart sequence.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean restart;
+  
+  /**
+   * Indicates whether the debuggee should be terminated when the debugger is disconnected.
+   * <p>
+   * If unspecified, the debug adapter is free to do whatever it thinks is best.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportTerminateDebuggee' is true.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean terminateDebuggee;
+  
+  /**
+   * A value of true indicates that this 'disconnect' request is part of a restart sequence.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getRestart() {
+    return this.restart;
+  }
+  
+  /**
+   * A value of true indicates that this 'disconnect' request is part of a restart sequence.
+   * <p>
+   * This is an optional property.
+   */
+  public void setRestart(final Boolean restart) {
+    this.restart = restart;
+  }
+  
+  /**
+   * Indicates whether the debuggee should be terminated when the debugger is disconnected.
+   * <p>
+   * If unspecified, the debug adapter is free to do whatever it thinks is best.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportTerminateDebuggee' is true.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getTerminateDebuggee() {
+    return this.terminateDebuggee;
+  }
+  
+  /**
+   * Indicates whether the debuggee should be terminated when the debugger is disconnected.
+   * <p>
+   * If unspecified, the debug adapter is free to do whatever it thinks is best.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportTerminateDebuggee' is true.
+   * <p>
+   * This is an optional property.
+   */
+  public void setTerminateDebuggee(final Boolean terminateDebuggee) {
+    this.terminateDebuggee = terminateDebuggee;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("restart", this.restart);
+    b.add("terminateDebuggee", this.terminateDebuggee);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    DisconnectArguments other = (DisconnectArguments) obj;
+    if (this.restart == null) {
+      if (other.restart != null)
+        return false;
+    } else if (!this.restart.equals(other.restart))
+      return false;
+    if (this.terminateDebuggee == null) {
+      if (other.terminateDebuggee != null)
+        return false;
+    } else if (!this.terminateDebuggee.equals(other.terminateDebuggee))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.restart== null) ? 0 : this.restart.hashCode());
+    return prime * result + ((this.terminateDebuggee== null) ? 0 : this.terminateDebuggee.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/EvaluateArguments.java b/java/org/eclipse/lsp4j/debug/EvaluateArguments.java
new file mode 100644
index 0000000..634b49a
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/EvaluateArguments.java
@@ -0,0 +1,194 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.ValueFormat;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'evaluate' request.
+ */
+@SuppressWarnings("all")
+public class EvaluateArguments {
+  /**
+   * The expression to evaluate.
+   */
+  @NonNull
+  private String expression;
+  
+  /**
+   * Evaluate the expression in the scope of this stack frame. If not specified, the expression is evaluated in the
+   * global scope.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer frameId;
+  
+  /**
+   * The context in which the evaluate request is run.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link EvaluateArgumentsContext}
+   */
+  private String context;
+  
+  /**
+   * Specifies details on how to format the Evaluate result.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportsValueFormattingOptions' is true.
+   * <p>
+   * This is an optional property.
+   */
+  private ValueFormat format;
+  
+  /**
+   * The expression to evaluate.
+   */
+  @Pure
+  @NonNull
+  public String getExpression() {
+    return this.expression;
+  }
+  
+  /**
+   * The expression to evaluate.
+   */
+  public void setExpression(@NonNull final String expression) {
+    this.expression = Preconditions.checkNotNull(expression, "expression");
+  }
+  
+  /**
+   * Evaluate the expression in the scope of this stack frame. If not specified, the expression is evaluated in the
+   * global scope.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getFrameId() {
+    return this.frameId;
+  }
+  
+  /**
+   * Evaluate the expression in the scope of this stack frame. If not specified, the expression is evaluated in the
+   * global scope.
+   * <p>
+   * This is an optional property.
+   */
+  public void setFrameId(final Integer frameId) {
+    this.frameId = frameId;
+  }
+  
+  /**
+   * The context in which the evaluate request is run.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link EvaluateArgumentsContext}
+   */
+  @Pure
+  public String getContext() {
+    return this.context;
+  }
+  
+  /**
+   * The context in which the evaluate request is run.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link EvaluateArgumentsContext}
+   */
+  public void setContext(final String context) {
+    this.context = context;
+  }
+  
+  /**
+   * Specifies details on how to format the Evaluate result.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportsValueFormattingOptions' is true.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public ValueFormat getFormat() {
+    return this.format;
+  }
+  
+  /**
+   * Specifies details on how to format the Evaluate result.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportsValueFormattingOptions' is true.
+   * <p>
+   * This is an optional property.
+   */
+  public void setFormat(final ValueFormat format) {
+    this.format = format;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("expression", this.expression);
+    b.add("frameId", this.frameId);
+    b.add("context", this.context);
+    b.add("format", this.format);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    EvaluateArguments other = (EvaluateArguments) obj;
+    if (this.expression == null) {
+      if (other.expression != null)
+        return false;
+    } else if (!this.expression.equals(other.expression))
+      return false;
+    if (this.frameId == null) {
+      if (other.frameId != null)
+        return false;
+    } else if (!this.frameId.equals(other.frameId))
+      return false;
+    if (this.context == null) {
+      if (other.context != null)
+        return false;
+    } else if (!this.context.equals(other.context))
+      return false;
+    if (this.format == null) {
+      if (other.format != null)
+        return false;
+    } else if (!this.format.equals(other.format))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.expression== null) ? 0 : this.expression.hashCode());
+    result = prime * result + ((this.frameId== null) ? 0 : this.frameId.hashCode());
+    result = prime * result + ((this.context== null) ? 0 : this.context.hashCode());
+    return prime * result + ((this.format== null) ? 0 : this.format.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/EvaluateArgumentsContext.java b/java/org/eclipse/lsp4j/debug/EvaluateArgumentsContext.java
new file mode 100644
index 0000000..0fa2764
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/EvaluateArgumentsContext.java
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+/**
+ * The context in which the evaluate request is run.
+ * <p>
+ * Possible values include - but not limited to those defined in {@link EvaluateArgumentsContext}
+ */
+@SuppressWarnings("all")
+public interface EvaluateArgumentsContext {
+  /**
+   * evaluate is run in a watch.
+   */
+  static final String WATCH = "watch";
+  
+  /**
+   * evaluate is run from REPL console.
+   */
+  static final String REPL = "repl";
+  
+  /**
+   * evaluate is run from a data hover.
+   */
+  static final String HOVER = "hover";
+  
+  /**
+   * evaluate is run to generate the value that will be stored in the clipboard.
+   * The attribute is only honored by a
+   * debug adapter if the capability 'supportsClipboardContext' is true.
+   */
+  static final String CLIPBOARD = "clipboard";
+}
diff --git a/java/org/eclipse/lsp4j/debug/EvaluateResponse.java b/java/org/eclipse/lsp4j/debug/EvaluateResponse.java
new file mode 100644
index 0000000..eaa3742
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/EvaluateResponse.java
@@ -0,0 +1,326 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.VariablePresentationHint;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Response to 'evaluate' request.
+ */
+@SuppressWarnings("all")
+public class EvaluateResponse {
+  /**
+   * The result of the evaluate request.
+   */
+  @NonNull
+  private String result;
+  
+  /**
+   * The optional type of the evaluate result.
+   * <p>
+   * This attribute should only be returned by a debug adapter if the client has passed the value true for the
+   * 'supportsVariableType' capability of the 'initialize' request.
+   * <p>
+   * This is an optional property.
+   */
+  private String type;
+  
+  /**
+   * Properties of a evaluate result that can be used to determine how to render the result in the UI.
+   * <p>
+   * This is an optional property.
+   */
+  private VariablePresentationHint presentationHint;
+  
+  /**
+   * If variablesReference is &gt; 0, the evaluate result is structured and its children can be retrieved by passing
+   * variablesReference to the VariablesRequest.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   */
+  private int variablesReference;
+  
+  /**
+   * The number of named child variables.
+   * <p>
+   * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  private Integer namedVariables;
+  
+  /**
+   * The number of indexed child variables.
+   * <p>
+   * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  private Integer indexedVariables;
+  
+  /**
+   * Optional memory reference to a location appropriate for this result.
+   * <p>
+   * For pointer type eval results, this is generally a reference to the memory address contained in the pointer.
+   * <p>
+   * This attribute should be returned by a debug adapter if the client has passed the value true for the
+   * 'supportsMemoryReferences' capability of the 'initialize' request.
+   * <p>
+   * This is an optional property.
+   */
+  private String memoryReference;
+  
+  /**
+   * The result of the evaluate request.
+   */
+  @Pure
+  @NonNull
+  public String getResult() {
+    return this.result;
+  }
+  
+  /**
+   * The result of the evaluate request.
+   */
+  public void setResult(@NonNull final String result) {
+    this.result = Preconditions.checkNotNull(result, "result");
+  }
+  
+  /**
+   * The optional type of the evaluate result.
+   * <p>
+   * This attribute should only be returned by a debug adapter if the client has passed the value true for the
+   * 'supportsVariableType' capability of the 'initialize' request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getType() {
+    return this.type;
+  }
+  
+  /**
+   * The optional type of the evaluate result.
+   * <p>
+   * This attribute should only be returned by a debug adapter if the client has passed the value true for the
+   * 'supportsVariableType' capability of the 'initialize' request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setType(final String type) {
+    this.type = type;
+  }
+  
+  /**
+   * Properties of a evaluate result that can be used to determine how to render the result in the UI.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public VariablePresentationHint getPresentationHint() {
+    return this.presentationHint;
+  }
+  
+  /**
+   * Properties of a evaluate result that can be used to determine how to render the result in the UI.
+   * <p>
+   * This is an optional property.
+   */
+  public void setPresentationHint(final VariablePresentationHint presentationHint) {
+    this.presentationHint = presentationHint;
+  }
+  
+  /**
+   * If variablesReference is &gt; 0, the evaluate result is structured and its children can be retrieved by passing
+   * variablesReference to the VariablesRequest.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   */
+  @Pure
+  public int getVariablesReference() {
+    return this.variablesReference;
+  }
+  
+  /**
+   * If variablesReference is &gt; 0, the evaluate result is structured and its children can be retrieved by passing
+   * variablesReference to the VariablesRequest.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   */
+  public void setVariablesReference(final int variablesReference) {
+    this.variablesReference = variablesReference;
+  }
+  
+  /**
+   * The number of named child variables.
+   * <p>
+   * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getNamedVariables() {
+    return this.namedVariables;
+  }
+  
+  /**
+   * The number of named child variables.
+   * <p>
+   * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  public void setNamedVariables(final Integer namedVariables) {
+    this.namedVariables = namedVariables;
+  }
+  
+  /**
+   * The number of indexed child variables.
+   * <p>
+   * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getIndexedVariables() {
+    return this.indexedVariables;
+  }
+  
+  /**
+   * The number of indexed child variables.
+   * <p>
+   * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  public void setIndexedVariables(final Integer indexedVariables) {
+    this.indexedVariables = indexedVariables;
+  }
+  
+  /**
+   * Optional memory reference to a location appropriate for this result.
+   * <p>
+   * For pointer type eval results, this is generally a reference to the memory address contained in the pointer.
+   * <p>
+   * This attribute should be returned by a debug adapter if the client has passed the value true for the
+   * 'supportsMemoryReferences' capability of the 'initialize' request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getMemoryReference() {
+    return this.memoryReference;
+  }
+  
+  /**
+   * Optional memory reference to a location appropriate for this result.
+   * <p>
+   * For pointer type eval results, this is generally a reference to the memory address contained in the pointer.
+   * <p>
+   * This attribute should be returned by a debug adapter if the client has passed the value true for the
+   * 'supportsMemoryReferences' capability of the 'initialize' request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setMemoryReference(final String memoryReference) {
+    this.memoryReference = memoryReference;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("result", this.result);
+    b.add("type", this.type);
+    b.add("presentationHint", this.presentationHint);
+    b.add("variablesReference", this.variablesReference);
+    b.add("namedVariables", this.namedVariables);
+    b.add("indexedVariables", this.indexedVariables);
+    b.add("memoryReference", this.memoryReference);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    EvaluateResponse other = (EvaluateResponse) obj;
+    if (this.result == null) {
+      if (other.result != null)
+        return false;
+    } else if (!this.result.equals(other.result))
+      return false;
+    if (this.type == null) {
+      if (other.type != null)
+        return false;
+    } else if (!this.type.equals(other.type))
+      return false;
+    if (this.presentationHint == null) {
+      if (other.presentationHint != null)
+        return false;
+    } else if (!this.presentationHint.equals(other.presentationHint))
+      return false;
+    if (other.variablesReference != this.variablesReference)
+      return false;
+    if (this.namedVariables == null) {
+      if (other.namedVariables != null)
+        return false;
+    } else if (!this.namedVariables.equals(other.namedVariables))
+      return false;
+    if (this.indexedVariables == null) {
+      if (other.indexedVariables != null)
+        return false;
+    } else if (!this.indexedVariables.equals(other.indexedVariables))
+      return false;
+    if (this.memoryReference == null) {
+      if (other.memoryReference != null)
+        return false;
+    } else if (!this.memoryReference.equals(other.memoryReference))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.result== null) ? 0 : this.result.hashCode());
+    result = prime * result + ((this.type== null) ? 0 : this.type.hashCode());
+    result = prime * result + ((this.presentationHint== null) ? 0 : this.presentationHint.hashCode());
+    result = prime * result + this.variablesReference;
+    result = prime * result + ((this.namedVariables== null) ? 0 : this.namedVariables.hashCode());
+    result = prime * result + ((this.indexedVariables== null) ? 0 : this.indexedVariables.hashCode());
+    return prime * result + ((this.memoryReference== null) ? 0 : this.memoryReference.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ExceptionBreakMode.java b/java/org/eclipse/lsp4j/debug/ExceptionBreakMode.java
new file mode 100644
index 0000000..b1b57c1
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ExceptionBreakMode.java
@@ -0,0 +1,34 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+/**
+ * This enumeration defines all possible conditions when a thrown exception should result in a break.
+ * <p>
+ * never: never breaks,
+ * <p>
+ * always: always breaks,
+ * <p>
+ * unhandled: breaks when exception unhandled,
+ * <p>
+ * userUnhandled: breaks if the exception is not handled by user code.
+ */
+@SuppressWarnings("all")
+public enum ExceptionBreakMode {
+  NEVER,
+  
+  ALWAYS,
+  
+  UNHANDLED,
+  
+  USER_UNHANDLED;
+}
diff --git a/java/org/eclipse/lsp4j/debug/ExceptionBreakpointsFilter.java b/java/org/eclipse/lsp4j/debug/ExceptionBreakpointsFilter.java
new file mode 100644
index 0000000..0576a05
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ExceptionBreakpointsFilter.java
@@ -0,0 +1,180 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import com.google.gson.annotations.SerializedName;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * An ExceptionBreakpointsFilter is shown in the UI as an filter option for configuring how exceptions are dealt
+ * with.
+ */
+@SuppressWarnings("all")
+public class ExceptionBreakpointsFilter {
+  /**
+   * The internal ID of the filter option. This value is passed to the 'setExceptionBreakpoints' request.
+   */
+  @NonNull
+  private String filter;
+  
+  /**
+   * The name of the filter option. This will be shown in the UI.
+   */
+  @NonNull
+  private String label;
+  
+  /**
+   * Initial value of the filter option. If not specified a value 'false' is assumed.
+   * <p>
+   * This is an optional property.
+   */
+  @SerializedName(value = "default")
+  private Boolean default_;
+  
+  /**
+   * Controls whether a condition can be specified for this filter option. If false or missing, a condition can not
+   * be set.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsCondition;
+  
+  /**
+   * The internal ID of the filter option. This value is passed to the 'setExceptionBreakpoints' request.
+   */
+  @Pure
+  @NonNull
+  public String getFilter() {
+    return this.filter;
+  }
+  
+  /**
+   * The internal ID of the filter option. This value is passed to the 'setExceptionBreakpoints' request.
+   */
+  public void setFilter(@NonNull final String filter) {
+    this.filter = Preconditions.checkNotNull(filter, "filter");
+  }
+  
+  /**
+   * The name of the filter option. This will be shown in the UI.
+   */
+  @Pure
+  @NonNull
+  public String getLabel() {
+    return this.label;
+  }
+  
+  /**
+   * The name of the filter option. This will be shown in the UI.
+   */
+  public void setLabel(@NonNull final String label) {
+    this.label = Preconditions.checkNotNull(label, "label");
+  }
+  
+  /**
+   * Initial value of the filter option. If not specified a value 'false' is assumed.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getDefault_() {
+    return this.default_;
+  }
+  
+  /**
+   * Initial value of the filter option. If not specified a value 'false' is assumed.
+   * <p>
+   * This is an optional property.
+   */
+  public void setDefault_(final Boolean default_) {
+    this.default_ = default_;
+  }
+  
+  /**
+   * Controls whether a condition can be specified for this filter option. If false or missing, a condition can not
+   * be set.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsCondition() {
+    return this.supportsCondition;
+  }
+  
+  /**
+   * Controls whether a condition can be specified for this filter option. If false or missing, a condition can not
+   * be set.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsCondition(final Boolean supportsCondition) {
+    this.supportsCondition = supportsCondition;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("filter", this.filter);
+    b.add("label", this.label);
+    b.add("default_", this.default_);
+    b.add("supportsCondition", this.supportsCondition);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ExceptionBreakpointsFilter other = (ExceptionBreakpointsFilter) obj;
+    if (this.filter == null) {
+      if (other.filter != null)
+        return false;
+    } else if (!this.filter.equals(other.filter))
+      return false;
+    if (this.label == null) {
+      if (other.label != null)
+        return false;
+    } else if (!this.label.equals(other.label))
+      return false;
+    if (this.default_ == null) {
+      if (other.default_ != null)
+        return false;
+    } else if (!this.default_.equals(other.default_))
+      return false;
+    if (this.supportsCondition == null) {
+      if (other.supportsCondition != null)
+        return false;
+    } else if (!this.supportsCondition.equals(other.supportsCondition))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.filter== null) ? 0 : this.filter.hashCode());
+    result = prime * result + ((this.label== null) ? 0 : this.label.hashCode());
+    result = prime * result + ((this.default_== null) ? 0 : this.default_.hashCode());
+    return prime * result + ((this.supportsCondition== null) ? 0 : this.supportsCondition.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ExceptionDetails.java b/java/org/eclipse/lsp4j/debug/ExceptionDetails.java
new file mode 100644
index 0000000..fcfd19c
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ExceptionDetails.java
@@ -0,0 +1,247 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Detailed information about an exception that has occurred.
+ */
+@SuppressWarnings("all")
+public class ExceptionDetails {
+  /**
+   * Message contained in the exception.
+   * <p>
+   * This is an optional property.
+   */
+  private String message;
+  
+  /**
+   * Short type name of the exception object.
+   * <p>
+   * This is an optional property.
+   */
+  private String typeName;
+  
+  /**
+   * Fully-qualified type name of the exception object.
+   * <p>
+   * This is an optional property.
+   */
+  private String fullTypeName;
+  
+  /**
+   * Optional expression that can be evaluated in the current scope to obtain the exception object.
+   * <p>
+   * This is an optional property.
+   */
+  private String evaluateName;
+  
+  /**
+   * Stack trace at the time the exception was thrown.
+   * <p>
+   * This is an optional property.
+   */
+  private String stackTrace;
+  
+  /**
+   * Details of the exception contained by this exception, if any.
+   * <p>
+   * This is an optional property.
+   */
+  private ExceptionDetails[] innerException;
+  
+  /**
+   * Message contained in the exception.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getMessage() {
+    return this.message;
+  }
+  
+  /**
+   * Message contained in the exception.
+   * <p>
+   * This is an optional property.
+   */
+  public void setMessage(final String message) {
+    this.message = message;
+  }
+  
+  /**
+   * Short type name of the exception object.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getTypeName() {
+    return this.typeName;
+  }
+  
+  /**
+   * Short type name of the exception object.
+   * <p>
+   * This is an optional property.
+   */
+  public void setTypeName(final String typeName) {
+    this.typeName = typeName;
+  }
+  
+  /**
+   * Fully-qualified type name of the exception object.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getFullTypeName() {
+    return this.fullTypeName;
+  }
+  
+  /**
+   * Fully-qualified type name of the exception object.
+   * <p>
+   * This is an optional property.
+   */
+  public void setFullTypeName(final String fullTypeName) {
+    this.fullTypeName = fullTypeName;
+  }
+  
+  /**
+   * Optional expression that can be evaluated in the current scope to obtain the exception object.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getEvaluateName() {
+    return this.evaluateName;
+  }
+  
+  /**
+   * Optional expression that can be evaluated in the current scope to obtain the exception object.
+   * <p>
+   * This is an optional property.
+   */
+  public void setEvaluateName(final String evaluateName) {
+    this.evaluateName = evaluateName;
+  }
+  
+  /**
+   * Stack trace at the time the exception was thrown.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getStackTrace() {
+    return this.stackTrace;
+  }
+  
+  /**
+   * Stack trace at the time the exception was thrown.
+   * <p>
+   * This is an optional property.
+   */
+  public void setStackTrace(final String stackTrace) {
+    this.stackTrace = stackTrace;
+  }
+  
+  /**
+   * Details of the exception contained by this exception, if any.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public ExceptionDetails[] getInnerException() {
+    return this.innerException;
+  }
+  
+  /**
+   * Details of the exception contained by this exception, if any.
+   * <p>
+   * This is an optional property.
+   */
+  public void setInnerException(final ExceptionDetails[] innerException) {
+    this.innerException = innerException;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("message", this.message);
+    b.add("typeName", this.typeName);
+    b.add("fullTypeName", this.fullTypeName);
+    b.add("evaluateName", this.evaluateName);
+    b.add("stackTrace", this.stackTrace);
+    b.add("innerException", this.innerException);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ExceptionDetails other = (ExceptionDetails) obj;
+    if (this.message == null) {
+      if (other.message != null)
+        return false;
+    } else if (!this.message.equals(other.message))
+      return false;
+    if (this.typeName == null) {
+      if (other.typeName != null)
+        return false;
+    } else if (!this.typeName.equals(other.typeName))
+      return false;
+    if (this.fullTypeName == null) {
+      if (other.fullTypeName != null)
+        return false;
+    } else if (!this.fullTypeName.equals(other.fullTypeName))
+      return false;
+    if (this.evaluateName == null) {
+      if (other.evaluateName != null)
+        return false;
+    } else if (!this.evaluateName.equals(other.evaluateName))
+      return false;
+    if (this.stackTrace == null) {
+      if (other.stackTrace != null)
+        return false;
+    } else if (!this.stackTrace.equals(other.stackTrace))
+      return false;
+    if (this.innerException == null) {
+      if (other.innerException != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.innerException, other.innerException))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.message== null) ? 0 : this.message.hashCode());
+    result = prime * result + ((this.typeName== null) ? 0 : this.typeName.hashCode());
+    result = prime * result + ((this.fullTypeName== null) ? 0 : this.fullTypeName.hashCode());
+    result = prime * result + ((this.evaluateName== null) ? 0 : this.evaluateName.hashCode());
+    result = prime * result + ((this.stackTrace== null) ? 0 : this.stackTrace.hashCode());
+    return prime * result + ((this.innerException== null) ? 0 : Arrays.deepHashCode(this.innerException));
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ExceptionFilterOptions.java b/java/org/eclipse/lsp4j/debug/ExceptionFilterOptions.java
new file mode 100644
index 0000000..17a1339
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ExceptionFilterOptions.java
@@ -0,0 +1,119 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * An ExceptionFilterOptions is used to specify an exception filter together with a condition for the
+ * setExceptionsFilter request.
+ */
+@SuppressWarnings("all")
+public class ExceptionFilterOptions {
+  /**
+   * ID of an exception filter returned by the 'exceptionBreakpointFilters' capability.
+   */
+  @NonNull
+  private String filterId;
+  
+  /**
+   * An optional expression for conditional exceptions.
+   * <p>
+   * The exception will break into the debugger if the result of the condition is true.
+   * <p>
+   * This is an optional property.
+   */
+  private String condition;
+  
+  /**
+   * ID of an exception filter returned by the 'exceptionBreakpointFilters' capability.
+   */
+  @Pure
+  @NonNull
+  public String getFilterId() {
+    return this.filterId;
+  }
+  
+  /**
+   * ID of an exception filter returned by the 'exceptionBreakpointFilters' capability.
+   */
+  public void setFilterId(@NonNull final String filterId) {
+    this.filterId = Preconditions.checkNotNull(filterId, "filterId");
+  }
+  
+  /**
+   * An optional expression for conditional exceptions.
+   * <p>
+   * The exception will break into the debugger if the result of the condition is true.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getCondition() {
+    return this.condition;
+  }
+  
+  /**
+   * An optional expression for conditional exceptions.
+   * <p>
+   * The exception will break into the debugger if the result of the condition is true.
+   * <p>
+   * This is an optional property.
+   */
+  public void setCondition(final String condition) {
+    this.condition = condition;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("filterId", this.filterId);
+    b.add("condition", this.condition);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ExceptionFilterOptions other = (ExceptionFilterOptions) obj;
+    if (this.filterId == null) {
+      if (other.filterId != null)
+        return false;
+    } else if (!this.filterId.equals(other.filterId))
+      return false;
+    if (this.condition == null) {
+      if (other.condition != null)
+        return false;
+    } else if (!this.condition.equals(other.condition))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.filterId== null) ? 0 : this.filterId.hashCode());
+    return prime * result + ((this.condition== null) ? 0 : this.condition.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ExceptionInfoArguments.java b/java/org/eclipse/lsp4j/debug/ExceptionInfoArguments.java
new file mode 100644
index 0000000..e49d42d
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ExceptionInfoArguments.java
@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'exceptionInfo' request.
+ */
+@SuppressWarnings("all")
+public class ExceptionInfoArguments {
+  /**
+   * Thread for which exception information should be retrieved.
+   */
+  private int threadId;
+  
+  /**
+   * Thread for which exception information should be retrieved.
+   */
+  @Pure
+  public int getThreadId() {
+    return this.threadId;
+  }
+  
+  /**
+   * Thread for which exception information should be retrieved.
+   */
+  public void setThreadId(final int threadId) {
+    this.threadId = threadId;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("threadId", this.threadId);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ExceptionInfoArguments other = (ExceptionInfoArguments) obj;
+    if (other.threadId != this.threadId)
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + this.threadId;
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ExceptionInfoResponse.java b/java/org/eclipse/lsp4j/debug/ExceptionInfoResponse.java
new file mode 100644
index 0000000..8223c6d
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ExceptionInfoResponse.java
@@ -0,0 +1,176 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.ExceptionBreakMode;
+import org.eclipse.lsp4j.debug.ExceptionDetails;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Response to 'exceptionInfo' request.
+ */
+@SuppressWarnings("all")
+public class ExceptionInfoResponse {
+  /**
+   * ID of the exception that was thrown.
+   */
+  @NonNull
+  private String exceptionId;
+  
+  /**
+   * Descriptive text for the exception provided by the debug adapter.
+   * <p>
+   * This is an optional property.
+   */
+  private String description;
+  
+  /**
+   * Mode that caused the exception notification to be raised.
+   */
+  @NonNull
+  private ExceptionBreakMode breakMode;
+  
+  /**
+   * Detailed information about the exception.
+   * <p>
+   * This is an optional property.
+   */
+  private ExceptionDetails details;
+  
+  /**
+   * ID of the exception that was thrown.
+   */
+  @Pure
+  @NonNull
+  public String getExceptionId() {
+    return this.exceptionId;
+  }
+  
+  /**
+   * ID of the exception that was thrown.
+   */
+  public void setExceptionId(@NonNull final String exceptionId) {
+    this.exceptionId = Preconditions.checkNotNull(exceptionId, "exceptionId");
+  }
+  
+  /**
+   * Descriptive text for the exception provided by the debug adapter.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getDescription() {
+    return this.description;
+  }
+  
+  /**
+   * Descriptive text for the exception provided by the debug adapter.
+   * <p>
+   * This is an optional property.
+   */
+  public void setDescription(final String description) {
+    this.description = description;
+  }
+  
+  /**
+   * Mode that caused the exception notification to be raised.
+   */
+  @Pure
+  @NonNull
+  public ExceptionBreakMode getBreakMode() {
+    return this.breakMode;
+  }
+  
+  /**
+   * Mode that caused the exception notification to be raised.
+   */
+  public void setBreakMode(@NonNull final ExceptionBreakMode breakMode) {
+    this.breakMode = Preconditions.checkNotNull(breakMode, "breakMode");
+  }
+  
+  /**
+   * Detailed information about the exception.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public ExceptionDetails getDetails() {
+    return this.details;
+  }
+  
+  /**
+   * Detailed information about the exception.
+   * <p>
+   * This is an optional property.
+   */
+  public void setDetails(final ExceptionDetails details) {
+    this.details = details;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("exceptionId", this.exceptionId);
+    b.add("description", this.description);
+    b.add("breakMode", this.breakMode);
+    b.add("details", this.details);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ExceptionInfoResponse other = (ExceptionInfoResponse) obj;
+    if (this.exceptionId == null) {
+      if (other.exceptionId != null)
+        return false;
+    } else if (!this.exceptionId.equals(other.exceptionId))
+      return false;
+    if (this.description == null) {
+      if (other.description != null)
+        return false;
+    } else if (!this.description.equals(other.description))
+      return false;
+    if (this.breakMode == null) {
+      if (other.breakMode != null)
+        return false;
+    } else if (!this.breakMode.equals(other.breakMode))
+      return false;
+    if (this.details == null) {
+      if (other.details != null)
+        return false;
+    } else if (!this.details.equals(other.details))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.exceptionId== null) ? 0 : this.exceptionId.hashCode());
+    result = prime * result + ((this.description== null) ? 0 : this.description.hashCode());
+    result = prime * result + ((this.breakMode== null) ? 0 : this.breakMode.hashCode());
+    return prime * result + ((this.details== null) ? 0 : this.details.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ExceptionOptions.java b/java/org/eclipse/lsp4j/debug/ExceptionOptions.java
new file mode 100644
index 0000000..25dadf3
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ExceptionOptions.java
@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.lsp4j.debug.ExceptionBreakMode;
+import org.eclipse.lsp4j.debug.ExceptionPathSegment;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * An ExceptionOptions assigns configuration options to a set of exceptions.
+ */
+@SuppressWarnings("all")
+public class ExceptionOptions {
+  /**
+   * A path that selects a single or multiple exceptions in a tree. If 'path' is missing, the whole tree is
+   * selected.
+   * <p>
+   * By convention the first segment of the path is a category that is used to group exceptions in the UI.
+   * <p>
+   * This is an optional property.
+   */
+  private ExceptionPathSegment[] path;
+  
+  /**
+   * Condition when a thrown exception should result in a break.
+   */
+  @NonNull
+  private ExceptionBreakMode breakMode;
+  
+  /**
+   * A path that selects a single or multiple exceptions in a tree. If 'path' is missing, the whole tree is
+   * selected.
+   * <p>
+   * By convention the first segment of the path is a category that is used to group exceptions in the UI.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public ExceptionPathSegment[] getPath() {
+    return this.path;
+  }
+  
+  /**
+   * A path that selects a single or multiple exceptions in a tree. If 'path' is missing, the whole tree is
+   * selected.
+   * <p>
+   * By convention the first segment of the path is a category that is used to group exceptions in the UI.
+   * <p>
+   * This is an optional property.
+   */
+  public void setPath(final ExceptionPathSegment[] path) {
+    this.path = path;
+  }
+  
+  /**
+   * Condition when a thrown exception should result in a break.
+   */
+  @Pure
+  @NonNull
+  public ExceptionBreakMode getBreakMode() {
+    return this.breakMode;
+  }
+  
+  /**
+   * Condition when a thrown exception should result in a break.
+   */
+  public void setBreakMode(@NonNull final ExceptionBreakMode breakMode) {
+    this.breakMode = Preconditions.checkNotNull(breakMode, "breakMode");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("path", this.path);
+    b.add("breakMode", this.breakMode);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ExceptionOptions other = (ExceptionOptions) obj;
+    if (this.path == null) {
+      if (other.path != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.path, other.path))
+      return false;
+    if (this.breakMode == null) {
+      if (other.breakMode != null)
+        return false;
+    } else if (!this.breakMode.equals(other.breakMode))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.path== null) ? 0 : Arrays.deepHashCode(this.path));
+    return prime * result + ((this.breakMode== null) ? 0 : this.breakMode.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ExceptionPathSegment.java b/java/org/eclipse/lsp4j/debug/ExceptionPathSegment.java
new file mode 100644
index 0000000..a9270d5
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ExceptionPathSegment.java
@@ -0,0 +1,121 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * An ExceptionPathSegment represents a segment in a path that is used to match leafs or nodes in a tree of
+ * exceptions.
+ * <p>
+ * If a segment consists of more than one name, it matches the names provided if 'negate' is false or missing or
+ * <p>
+ * it matches anything except the names provided if 'negate' is true.
+ */
+@SuppressWarnings("all")
+public class ExceptionPathSegment {
+  /**
+   * If false or missing this segment matches the names provided, otherwise it matches anything except the names
+   * provided.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean negate;
+  
+  /**
+   * Depending on the value of 'negate' the names that should match or not match.
+   */
+  @NonNull
+  private String[] names;
+  
+  /**
+   * If false or missing this segment matches the names provided, otherwise it matches anything except the names
+   * provided.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getNegate() {
+    return this.negate;
+  }
+  
+  /**
+   * If false or missing this segment matches the names provided, otherwise it matches anything except the names
+   * provided.
+   * <p>
+   * This is an optional property.
+   */
+  public void setNegate(final Boolean negate) {
+    this.negate = negate;
+  }
+  
+  /**
+   * Depending on the value of 'negate' the names that should match or not match.
+   */
+  @Pure
+  @NonNull
+  public String[] getNames() {
+    return this.names;
+  }
+  
+  /**
+   * Depending on the value of 'negate' the names that should match or not match.
+   */
+  public void setNames(@NonNull final String[] names) {
+    this.names = Preconditions.checkNotNull(names, "names");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("negate", this.negate);
+    b.add("names", this.names);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ExceptionPathSegment other = (ExceptionPathSegment) obj;
+    if (this.negate == null) {
+      if (other.negate != null)
+        return false;
+    } else if (!this.negate.equals(other.negate))
+      return false;
+    if (this.names == null) {
+      if (other.names != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.names, other.names))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.negate== null) ? 0 : this.negate.hashCode());
+    return prime * result + ((this.names== null) ? 0 : Arrays.deepHashCode(this.names));
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ExitedEventArguments.java b/java/org/eclipse/lsp4j/debug/ExitedEventArguments.java
new file mode 100644
index 0000000..7e69e53
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ExitedEventArguments.java
@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The event indicates that the debuggee has exited and returns its exit code.
+ */
+@SuppressWarnings("all")
+public class ExitedEventArguments {
+  /**
+   * The exit code returned from the debuggee.
+   */
+  private int exitCode;
+  
+  /**
+   * The exit code returned from the debuggee.
+   */
+  @Pure
+  public int getExitCode() {
+    return this.exitCode;
+  }
+  
+  /**
+   * The exit code returned from the debuggee.
+   */
+  public void setExitCode(final int exitCode) {
+    this.exitCode = exitCode;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("exitCode", this.exitCode);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ExitedEventArguments other = (ExitedEventArguments) obj;
+    if (other.exitCode != this.exitCode)
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + this.exitCode;
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/FunctionBreakpoint.java b/java/org/eclipse/lsp4j/debug/FunctionBreakpoint.java
new file mode 100644
index 0000000..6167245
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/FunctionBreakpoint.java
@@ -0,0 +1,163 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Properties of a breakpoint passed to the setFunctionBreakpoints request.
+ */
+@SuppressWarnings("all")
+public class FunctionBreakpoint {
+  /**
+   * The name of the function.
+   */
+  @NonNull
+  private String name;
+  
+  /**
+   * An optional expression for conditional breakpoints.
+   * <p>
+   * It is only honored by a debug adapter if the capability 'supportsConditionalBreakpoints' is true.
+   * <p>
+   * This is an optional property.
+   */
+  private String condition;
+  
+  /**
+   * An optional expression that controls how many hits of the breakpoint are ignored.
+   * <p>
+   * The backend is expected to interpret the expression as needed.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportsHitConditionalBreakpoints' is true.
+   * <p>
+   * This is an optional property.
+   */
+  private String hitCondition;
+  
+  /**
+   * The name of the function.
+   */
+  @Pure
+  @NonNull
+  public String getName() {
+    return this.name;
+  }
+  
+  /**
+   * The name of the function.
+   */
+  public void setName(@NonNull final String name) {
+    this.name = Preconditions.checkNotNull(name, "name");
+  }
+  
+  /**
+   * An optional expression for conditional breakpoints.
+   * <p>
+   * It is only honored by a debug adapter if the capability 'supportsConditionalBreakpoints' is true.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getCondition() {
+    return this.condition;
+  }
+  
+  /**
+   * An optional expression for conditional breakpoints.
+   * <p>
+   * It is only honored by a debug adapter if the capability 'supportsConditionalBreakpoints' is true.
+   * <p>
+   * This is an optional property.
+   */
+  public void setCondition(final String condition) {
+    this.condition = condition;
+  }
+  
+  /**
+   * An optional expression that controls how many hits of the breakpoint are ignored.
+   * <p>
+   * The backend is expected to interpret the expression as needed.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportsHitConditionalBreakpoints' is true.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getHitCondition() {
+    return this.hitCondition;
+  }
+  
+  /**
+   * An optional expression that controls how many hits of the breakpoint are ignored.
+   * <p>
+   * The backend is expected to interpret the expression as needed.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportsHitConditionalBreakpoints' is true.
+   * <p>
+   * This is an optional property.
+   */
+  public void setHitCondition(final String hitCondition) {
+    this.hitCondition = hitCondition;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("name", this.name);
+    b.add("condition", this.condition);
+    b.add("hitCondition", this.hitCondition);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    FunctionBreakpoint other = (FunctionBreakpoint) obj;
+    if (this.name == null) {
+      if (other.name != null)
+        return false;
+    } else if (!this.name.equals(other.name))
+      return false;
+    if (this.condition == null) {
+      if (other.condition != null)
+        return false;
+    } else if (!this.condition.equals(other.condition))
+      return false;
+    if (this.hitCondition == null) {
+      if (other.hitCondition != null)
+        return false;
+    } else if (!this.hitCondition.equals(other.hitCondition))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.name== null) ? 0 : this.name.hashCode());
+    result = prime * result + ((this.condition== null) ? 0 : this.condition.hashCode());
+    return prime * result + ((this.hitCondition== null) ? 0 : this.hitCondition.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/GotoArguments.java b/java/org/eclipse/lsp4j/debug/GotoArguments.java
new file mode 100644
index 0000000..bf699c2
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/GotoArguments.java
@@ -0,0 +1,96 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'goto' request.
+ */
+@SuppressWarnings("all")
+public class GotoArguments {
+  /**
+   * Set the goto target for this thread.
+   */
+  private int threadId;
+  
+  /**
+   * The location where the debuggee will continue to run.
+   */
+  private int targetId;
+  
+  /**
+   * Set the goto target for this thread.
+   */
+  @Pure
+  public int getThreadId() {
+    return this.threadId;
+  }
+  
+  /**
+   * Set the goto target for this thread.
+   */
+  public void setThreadId(final int threadId) {
+    this.threadId = threadId;
+  }
+  
+  /**
+   * The location where the debuggee will continue to run.
+   */
+  @Pure
+  public int getTargetId() {
+    return this.targetId;
+  }
+  
+  /**
+   * The location where the debuggee will continue to run.
+   */
+  public void setTargetId(final int targetId) {
+    this.targetId = targetId;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("threadId", this.threadId);
+    b.add("targetId", this.targetId);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    GotoArguments other = (GotoArguments) obj;
+    if (other.threadId != this.threadId)
+      return false;
+    if (other.targetId != this.targetId)
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + this.threadId;
+    return prime * result + this.targetId;
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/GotoTarget.java b/java/org/eclipse/lsp4j/debug/GotoTarget.java
new file mode 100644
index 0000000..5d64972
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/GotoTarget.java
@@ -0,0 +1,261 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A GotoTarget describes a code location that can be used as a target in the 'goto' request.
+ * <p>
+ * The possible goto targets can be determined via the 'gotoTargets' request.
+ */
+@SuppressWarnings("all")
+public class GotoTarget {
+  /**
+   * Unique identifier for a goto target. This is used in the goto request.
+   */
+  private int id;
+  
+  /**
+   * The name of the goto target (shown in the UI).
+   */
+  @NonNull
+  private String label;
+  
+  /**
+   * The line of the goto target.
+   */
+  private int line;
+  
+  /**
+   * An optional column of the goto target.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer column;
+  
+  /**
+   * An optional end line of the range covered by the goto target.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer endLine;
+  
+  /**
+   * An optional end column of the range covered by the goto target.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer endColumn;
+  
+  /**
+   * Optional memory reference for the instruction pointer value represented by this target.
+   * <p>
+   * This is an optional property.
+   */
+  private String instructionPointerReference;
+  
+  /**
+   * Unique identifier for a goto target. This is used in the goto request.
+   */
+  @Pure
+  public int getId() {
+    return this.id;
+  }
+  
+  /**
+   * Unique identifier for a goto target. This is used in the goto request.
+   */
+  public void setId(final int id) {
+    this.id = id;
+  }
+  
+  /**
+   * The name of the goto target (shown in the UI).
+   */
+  @Pure
+  @NonNull
+  public String getLabel() {
+    return this.label;
+  }
+  
+  /**
+   * The name of the goto target (shown in the UI).
+   */
+  public void setLabel(@NonNull final String label) {
+    this.label = Preconditions.checkNotNull(label, "label");
+  }
+  
+  /**
+   * The line of the goto target.
+   */
+  @Pure
+  public int getLine() {
+    return this.line;
+  }
+  
+  /**
+   * The line of the goto target.
+   */
+  public void setLine(final int line) {
+    this.line = line;
+  }
+  
+  /**
+   * An optional column of the goto target.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getColumn() {
+    return this.column;
+  }
+  
+  /**
+   * An optional column of the goto target.
+   * <p>
+   * This is an optional property.
+   */
+  public void setColumn(final Integer column) {
+    this.column = column;
+  }
+  
+  /**
+   * An optional end line of the range covered by the goto target.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getEndLine() {
+    return this.endLine;
+  }
+  
+  /**
+   * An optional end line of the range covered by the goto target.
+   * <p>
+   * This is an optional property.
+   */
+  public void setEndLine(final Integer endLine) {
+    this.endLine = endLine;
+  }
+  
+  /**
+   * An optional end column of the range covered by the goto target.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getEndColumn() {
+    return this.endColumn;
+  }
+  
+  /**
+   * An optional end column of the range covered by the goto target.
+   * <p>
+   * This is an optional property.
+   */
+  public void setEndColumn(final Integer endColumn) {
+    this.endColumn = endColumn;
+  }
+  
+  /**
+   * Optional memory reference for the instruction pointer value represented by this target.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getInstructionPointerReference() {
+    return this.instructionPointerReference;
+  }
+  
+  /**
+   * Optional memory reference for the instruction pointer value represented by this target.
+   * <p>
+   * This is an optional property.
+   */
+  public void setInstructionPointerReference(final String instructionPointerReference) {
+    this.instructionPointerReference = instructionPointerReference;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("id", this.id);
+    b.add("label", this.label);
+    b.add("line", this.line);
+    b.add("column", this.column);
+    b.add("endLine", this.endLine);
+    b.add("endColumn", this.endColumn);
+    b.add("instructionPointerReference", this.instructionPointerReference);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    GotoTarget other = (GotoTarget) obj;
+    if (other.id != this.id)
+      return false;
+    if (this.label == null) {
+      if (other.label != null)
+        return false;
+    } else if (!this.label.equals(other.label))
+      return false;
+    if (other.line != this.line)
+      return false;
+    if (this.column == null) {
+      if (other.column != null)
+        return false;
+    } else if (!this.column.equals(other.column))
+      return false;
+    if (this.endLine == null) {
+      if (other.endLine != null)
+        return false;
+    } else if (!this.endLine.equals(other.endLine))
+      return false;
+    if (this.endColumn == null) {
+      if (other.endColumn != null)
+        return false;
+    } else if (!this.endColumn.equals(other.endColumn))
+      return false;
+    if (this.instructionPointerReference == null) {
+      if (other.instructionPointerReference != null)
+        return false;
+    } else if (!this.instructionPointerReference.equals(other.instructionPointerReference))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + this.id;
+    result = prime * result + ((this.label== null) ? 0 : this.label.hashCode());
+    result = prime * result + this.line;
+    result = prime * result + ((this.column== null) ? 0 : this.column.hashCode());
+    result = prime * result + ((this.endLine== null) ? 0 : this.endLine.hashCode());
+    result = prime * result + ((this.endColumn== null) ? 0 : this.endColumn.hashCode());
+    return prime * result + ((this.instructionPointerReference== null) ? 0 : this.instructionPointerReference.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/GotoTargetsArguments.java b/java/org/eclipse/lsp4j/debug/GotoTargetsArguments.java
new file mode 100644
index 0000000..27aedd7
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/GotoTargetsArguments.java
@@ -0,0 +1,137 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.Source;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'gotoTargets' request.
+ */
+@SuppressWarnings("all")
+public class GotoTargetsArguments {
+  /**
+   * The source location for which the goto targets are determined.
+   */
+  @NonNull
+  private Source source;
+  
+  /**
+   * The line location for which the goto targets are determined.
+   */
+  private int line;
+  
+  /**
+   * An optional column location for which the goto targets are determined.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer column;
+  
+  /**
+   * The source location for which the goto targets are determined.
+   */
+  @Pure
+  @NonNull
+  public Source getSource() {
+    return this.source;
+  }
+  
+  /**
+   * The source location for which the goto targets are determined.
+   */
+  public void setSource(@NonNull final Source source) {
+    this.source = Preconditions.checkNotNull(source, "source");
+  }
+  
+  /**
+   * The line location for which the goto targets are determined.
+   */
+  @Pure
+  public int getLine() {
+    return this.line;
+  }
+  
+  /**
+   * The line location for which the goto targets are determined.
+   */
+  public void setLine(final int line) {
+    this.line = line;
+  }
+  
+  /**
+   * An optional column location for which the goto targets are determined.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getColumn() {
+    return this.column;
+  }
+  
+  /**
+   * An optional column location for which the goto targets are determined.
+   * <p>
+   * This is an optional property.
+   */
+  public void setColumn(final Integer column) {
+    this.column = column;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("source", this.source);
+    b.add("line", this.line);
+    b.add("column", this.column);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    GotoTargetsArguments other = (GotoTargetsArguments) obj;
+    if (this.source == null) {
+      if (other.source != null)
+        return false;
+    } else if (!this.source.equals(other.source))
+      return false;
+    if (other.line != this.line)
+      return false;
+    if (this.column == null) {
+      if (other.column != null)
+        return false;
+    } else if (!this.column.equals(other.column))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.source== null) ? 0 : this.source.hashCode());
+    result = prime * result + this.line;
+    return prime * result + ((this.column== null) ? 0 : this.column.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/GotoTargetsResponse.java b/java/org/eclipse/lsp4j/debug/GotoTargetsResponse.java
new file mode 100644
index 0000000..1ad134d
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/GotoTargetsResponse.java
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.lsp4j.debug.GotoTarget;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Response to 'gotoTargets' request.
+ */
+@SuppressWarnings("all")
+public class GotoTargetsResponse {
+  /**
+   * The possible goto targets of the specified location.
+   */
+  @NonNull
+  private GotoTarget[] targets;
+  
+  /**
+   * The possible goto targets of the specified location.
+   */
+  @Pure
+  @NonNull
+  public GotoTarget[] getTargets() {
+    return this.targets;
+  }
+  
+  /**
+   * The possible goto targets of the specified location.
+   */
+  public void setTargets(@NonNull final GotoTarget[] targets) {
+    this.targets = Preconditions.checkNotNull(targets, "targets");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("targets", this.targets);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    GotoTargetsResponse other = (GotoTargetsResponse) obj;
+    if (this.targets == null) {
+      if (other.targets != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.targets, other.targets))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.targets== null) ? 0 : Arrays.deepHashCode(this.targets));
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/InitializeRequestArguments.java b/java/org/eclipse/lsp4j/debug/InitializeRequestArguments.java
new file mode 100644
index 0000000..2f1d520
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/InitializeRequestArguments.java
@@ -0,0 +1,481 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'initialize' request.
+ */
+@SuppressWarnings("all")
+public class InitializeRequestArguments {
+  /**
+   * The ID of the (frontend) client using this adapter.
+   * <p>
+   * This is an optional property.
+   */
+  private String clientID;
+  
+  /**
+   * The human readable name of the (frontend) client using this adapter.
+   * <p>
+   * This is an optional property.
+   */
+  private String clientName;
+  
+  /**
+   * The ID of the debug adapter.
+   */
+  @NonNull
+  private String adapterID;
+  
+  /**
+   * The ISO-639 locale of the (frontend) client using this adapter, e.g. en-US or de-CH.
+   * <p>
+   * This is an optional property.
+   */
+  private String locale;
+  
+  /**
+   * If true all line numbers are 1-based (default).
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean linesStartAt1;
+  
+  /**
+   * If true all column numbers are 1-based (default).
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean columnsStartAt1;
+  
+  /**
+   * Determines in what format paths are specified. The default is 'path', which is the native format.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link InitializeRequestArgumentsPathFormat}
+   */
+  private String pathFormat;
+  
+  /**
+   * Client supports the optional type attribute for variables.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsVariableType;
+  
+  /**
+   * Client supports the paging of variables.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsVariablePaging;
+  
+  /**
+   * Client supports the runInTerminal request.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsRunInTerminalRequest;
+  
+  /**
+   * Client supports memory references.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsMemoryReferences;
+  
+  /**
+   * Client supports progress reporting.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsProgressReporting;
+  
+  /**
+   * Client supports the invalidated event.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean supportsInvalidatedEvent;
+  
+  /**
+   * The ID of the (frontend) client using this adapter.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getClientID() {
+    return this.clientID;
+  }
+  
+  /**
+   * The ID of the (frontend) client using this adapter.
+   * <p>
+   * This is an optional property.
+   */
+  public void setClientID(final String clientID) {
+    this.clientID = clientID;
+  }
+  
+  /**
+   * The human readable name of the (frontend) client using this adapter.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getClientName() {
+    return this.clientName;
+  }
+  
+  /**
+   * The human readable name of the (frontend) client using this adapter.
+   * <p>
+   * This is an optional property.
+   */
+  public void setClientName(final String clientName) {
+    this.clientName = clientName;
+  }
+  
+  /**
+   * The ID of the debug adapter.
+   */
+  @Pure
+  @NonNull
+  public String getAdapterID() {
+    return this.adapterID;
+  }
+  
+  /**
+   * The ID of the debug adapter.
+   */
+  public void setAdapterID(@NonNull final String adapterID) {
+    this.adapterID = Preconditions.checkNotNull(adapterID, "adapterID");
+  }
+  
+  /**
+   * The ISO-639 locale of the (frontend) client using this adapter, e.g. en-US or de-CH.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getLocale() {
+    return this.locale;
+  }
+  
+  /**
+   * The ISO-639 locale of the (frontend) client using this adapter, e.g. en-US or de-CH.
+   * <p>
+   * This is an optional property.
+   */
+  public void setLocale(final String locale) {
+    this.locale = locale;
+  }
+  
+  /**
+   * If true all line numbers are 1-based (default).
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getLinesStartAt1() {
+    return this.linesStartAt1;
+  }
+  
+  /**
+   * If true all line numbers are 1-based (default).
+   * <p>
+   * This is an optional property.
+   */
+  public void setLinesStartAt1(final Boolean linesStartAt1) {
+    this.linesStartAt1 = linesStartAt1;
+  }
+  
+  /**
+   * If true all column numbers are 1-based (default).
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getColumnsStartAt1() {
+    return this.columnsStartAt1;
+  }
+  
+  /**
+   * If true all column numbers are 1-based (default).
+   * <p>
+   * This is an optional property.
+   */
+  public void setColumnsStartAt1(final Boolean columnsStartAt1) {
+    this.columnsStartAt1 = columnsStartAt1;
+  }
+  
+  /**
+   * Determines in what format paths are specified. The default is 'path', which is the native format.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link InitializeRequestArgumentsPathFormat}
+   */
+  @Pure
+  public String getPathFormat() {
+    return this.pathFormat;
+  }
+  
+  /**
+   * Determines in what format paths are specified. The default is 'path', which is the native format.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link InitializeRequestArgumentsPathFormat}
+   */
+  public void setPathFormat(final String pathFormat) {
+    this.pathFormat = pathFormat;
+  }
+  
+  /**
+   * Client supports the optional type attribute for variables.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsVariableType() {
+    return this.supportsVariableType;
+  }
+  
+  /**
+   * Client supports the optional type attribute for variables.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsVariableType(final Boolean supportsVariableType) {
+    this.supportsVariableType = supportsVariableType;
+  }
+  
+  /**
+   * Client supports the paging of variables.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsVariablePaging() {
+    return this.supportsVariablePaging;
+  }
+  
+  /**
+   * Client supports the paging of variables.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsVariablePaging(final Boolean supportsVariablePaging) {
+    this.supportsVariablePaging = supportsVariablePaging;
+  }
+  
+  /**
+   * Client supports the runInTerminal request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsRunInTerminalRequest() {
+    return this.supportsRunInTerminalRequest;
+  }
+  
+  /**
+   * Client supports the runInTerminal request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsRunInTerminalRequest(final Boolean supportsRunInTerminalRequest) {
+    this.supportsRunInTerminalRequest = supportsRunInTerminalRequest;
+  }
+  
+  /**
+   * Client supports memory references.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsMemoryReferences() {
+    return this.supportsMemoryReferences;
+  }
+  
+  /**
+   * Client supports memory references.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsMemoryReferences(final Boolean supportsMemoryReferences) {
+    this.supportsMemoryReferences = supportsMemoryReferences;
+  }
+  
+  /**
+   * Client supports progress reporting.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsProgressReporting() {
+    return this.supportsProgressReporting;
+  }
+  
+  /**
+   * Client supports progress reporting.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsProgressReporting(final Boolean supportsProgressReporting) {
+    this.supportsProgressReporting = supportsProgressReporting;
+  }
+  
+  /**
+   * Client supports the invalidated event.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSupportsInvalidatedEvent() {
+    return this.supportsInvalidatedEvent;
+  }
+  
+  /**
+   * Client supports the invalidated event.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSupportsInvalidatedEvent(final Boolean supportsInvalidatedEvent) {
+    this.supportsInvalidatedEvent = supportsInvalidatedEvent;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("clientID", this.clientID);
+    b.add("clientName", this.clientName);
+    b.add("adapterID", this.adapterID);
+    b.add("locale", this.locale);
+    b.add("linesStartAt1", this.linesStartAt1);
+    b.add("columnsStartAt1", this.columnsStartAt1);
+    b.add("pathFormat", this.pathFormat);
+    b.add("supportsVariableType", this.supportsVariableType);
+    b.add("supportsVariablePaging", this.supportsVariablePaging);
+    b.add("supportsRunInTerminalRequest", this.supportsRunInTerminalRequest);
+    b.add("supportsMemoryReferences", this.supportsMemoryReferences);
+    b.add("supportsProgressReporting", this.supportsProgressReporting);
+    b.add("supportsInvalidatedEvent", this.supportsInvalidatedEvent);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    InitializeRequestArguments other = (InitializeRequestArguments) obj;
+    if (this.clientID == null) {
+      if (other.clientID != null)
+        return false;
+    } else if (!this.clientID.equals(other.clientID))
+      return false;
+    if (this.clientName == null) {
+      if (other.clientName != null)
+        return false;
+    } else if (!this.clientName.equals(other.clientName))
+      return false;
+    if (this.adapterID == null) {
+      if (other.adapterID != null)
+        return false;
+    } else if (!this.adapterID.equals(other.adapterID))
+      return false;
+    if (this.locale == null) {
+      if (other.locale != null)
+        return false;
+    } else if (!this.locale.equals(other.locale))
+      return false;
+    if (this.linesStartAt1 == null) {
+      if (other.linesStartAt1 != null)
+        return false;
+    } else if (!this.linesStartAt1.equals(other.linesStartAt1))
+      return false;
+    if (this.columnsStartAt1 == null) {
+      if (other.columnsStartAt1 != null)
+        return false;
+    } else if (!this.columnsStartAt1.equals(other.columnsStartAt1))
+      return false;
+    if (this.pathFormat == null) {
+      if (other.pathFormat != null)
+        return false;
+    } else if (!this.pathFormat.equals(other.pathFormat))
+      return false;
+    if (this.supportsVariableType == null) {
+      if (other.supportsVariableType != null)
+        return false;
+    } else if (!this.supportsVariableType.equals(other.supportsVariableType))
+      return false;
+    if (this.supportsVariablePaging == null) {
+      if (other.supportsVariablePaging != null)
+        return false;
+    } else if (!this.supportsVariablePaging.equals(other.supportsVariablePaging))
+      return false;
+    if (this.supportsRunInTerminalRequest == null) {
+      if (other.supportsRunInTerminalRequest != null)
+        return false;
+    } else if (!this.supportsRunInTerminalRequest.equals(other.supportsRunInTerminalRequest))
+      return false;
+    if (this.supportsMemoryReferences == null) {
+      if (other.supportsMemoryReferences != null)
+        return false;
+    } else if (!this.supportsMemoryReferences.equals(other.supportsMemoryReferences))
+      return false;
+    if (this.supportsProgressReporting == null) {
+      if (other.supportsProgressReporting != null)
+        return false;
+    } else if (!this.supportsProgressReporting.equals(other.supportsProgressReporting))
+      return false;
+    if (this.supportsInvalidatedEvent == null) {
+      if (other.supportsInvalidatedEvent != null)
+        return false;
+    } else if (!this.supportsInvalidatedEvent.equals(other.supportsInvalidatedEvent))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.clientID== null) ? 0 : this.clientID.hashCode());
+    result = prime * result + ((this.clientName== null) ? 0 : this.clientName.hashCode());
+    result = prime * result + ((this.adapterID== null) ? 0 : this.adapterID.hashCode());
+    result = prime * result + ((this.locale== null) ? 0 : this.locale.hashCode());
+    result = prime * result + ((this.linesStartAt1== null) ? 0 : this.linesStartAt1.hashCode());
+    result = prime * result + ((this.columnsStartAt1== null) ? 0 : this.columnsStartAt1.hashCode());
+    result = prime * result + ((this.pathFormat== null) ? 0 : this.pathFormat.hashCode());
+    result = prime * result + ((this.supportsVariableType== null) ? 0 : this.supportsVariableType.hashCode());
+    result = prime * result + ((this.supportsVariablePaging== null) ? 0 : this.supportsVariablePaging.hashCode());
+    result = prime * result + ((this.supportsRunInTerminalRequest== null) ? 0 : this.supportsRunInTerminalRequest.hashCode());
+    result = prime * result + ((this.supportsMemoryReferences== null) ? 0 : this.supportsMemoryReferences.hashCode());
+    result = prime * result + ((this.supportsProgressReporting== null) ? 0 : this.supportsProgressReporting.hashCode());
+    return prime * result + ((this.supportsInvalidatedEvent== null) ? 0 : this.supportsInvalidatedEvent.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/InitializeRequestArgumentsPathFormat.java b/java/org/eclipse/lsp4j/debug/InitializeRequestArgumentsPathFormat.java
new file mode 100644
index 0000000..ff643b0
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/InitializeRequestArgumentsPathFormat.java
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+/**
+ * Determines in what format paths are specified. The default is 'path', which is the native format.
+ * <p>
+ * Possible values include - but not limited to those defined in {@link InitializeRequestArgumentsPathFormat}
+ */
+@SuppressWarnings("all")
+public interface InitializeRequestArgumentsPathFormat {
+  static final String PATH = "path";
+  
+  static final String URI = "uri";
+}
diff --git a/java/org/eclipse/lsp4j/debug/InstructionBreakpoint.java b/java/org/eclipse/lsp4j/debug/InstructionBreakpoint.java
new file mode 100644
index 0000000..190f1a0
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/InstructionBreakpoint.java
@@ -0,0 +1,211 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Properties of a breakpoint passed to the setInstructionBreakpoints request
+ */
+@SuppressWarnings("all")
+public class InstructionBreakpoint {
+  /**
+   * The instruction reference of the breakpoint.
+   * <p>
+   * This should be a memory or instruction pointer reference from an EvaluateResponse, Variable, StackFrame,
+   * GotoTarget, or Breakpoint.
+   */
+  @NonNull
+  private String instructionReference;
+  
+  /**
+   * An optional offset from the instruction reference.
+   * <p>
+   * This can be negative.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer offset;
+  
+  /**
+   * An optional expression for conditional breakpoints.
+   * <p>
+   * It is only honored by a debug adapter if the capability 'supportsConditionalBreakpoints' is true.
+   * <p>
+   * This is an optional property.
+   */
+  private String condition;
+  
+  /**
+   * An optional expression that controls how many hits of the breakpoint are ignored.
+   * <p>
+   * The backend is expected to interpret the expression as needed.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportsHitConditionalBreakpoints' is true.
+   * <p>
+   * This is an optional property.
+   */
+  private String hitCondition;
+  
+  /**
+   * The instruction reference of the breakpoint.
+   * <p>
+   * This should be a memory or instruction pointer reference from an EvaluateResponse, Variable, StackFrame,
+   * GotoTarget, or Breakpoint.
+   */
+  @Pure
+  @NonNull
+  public String getInstructionReference() {
+    return this.instructionReference;
+  }
+  
+  /**
+   * The instruction reference of the breakpoint.
+   * <p>
+   * This should be a memory or instruction pointer reference from an EvaluateResponse, Variable, StackFrame,
+   * GotoTarget, or Breakpoint.
+   */
+  public void setInstructionReference(@NonNull final String instructionReference) {
+    this.instructionReference = Preconditions.checkNotNull(instructionReference, "instructionReference");
+  }
+  
+  /**
+   * An optional offset from the instruction reference.
+   * <p>
+   * This can be negative.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getOffset() {
+    return this.offset;
+  }
+  
+  /**
+   * An optional offset from the instruction reference.
+   * <p>
+   * This can be negative.
+   * <p>
+   * This is an optional property.
+   */
+  public void setOffset(final Integer offset) {
+    this.offset = offset;
+  }
+  
+  /**
+   * An optional expression for conditional breakpoints.
+   * <p>
+   * It is only honored by a debug adapter if the capability 'supportsConditionalBreakpoints' is true.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getCondition() {
+    return this.condition;
+  }
+  
+  /**
+   * An optional expression for conditional breakpoints.
+   * <p>
+   * It is only honored by a debug adapter if the capability 'supportsConditionalBreakpoints' is true.
+   * <p>
+   * This is an optional property.
+   */
+  public void setCondition(final String condition) {
+    this.condition = condition;
+  }
+  
+  /**
+   * An optional expression that controls how many hits of the breakpoint are ignored.
+   * <p>
+   * The backend is expected to interpret the expression as needed.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportsHitConditionalBreakpoints' is true.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getHitCondition() {
+    return this.hitCondition;
+  }
+  
+  /**
+   * An optional expression that controls how many hits of the breakpoint are ignored.
+   * <p>
+   * The backend is expected to interpret the expression as needed.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportsHitConditionalBreakpoints' is true.
+   * <p>
+   * This is an optional property.
+   */
+  public void setHitCondition(final String hitCondition) {
+    this.hitCondition = hitCondition;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("instructionReference", this.instructionReference);
+    b.add("offset", this.offset);
+    b.add("condition", this.condition);
+    b.add("hitCondition", this.hitCondition);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    InstructionBreakpoint other = (InstructionBreakpoint) obj;
+    if (this.instructionReference == null) {
+      if (other.instructionReference != null)
+        return false;
+    } else if (!this.instructionReference.equals(other.instructionReference))
+      return false;
+    if (this.offset == null) {
+      if (other.offset != null)
+        return false;
+    } else if (!this.offset.equals(other.offset))
+      return false;
+    if (this.condition == null) {
+      if (other.condition != null)
+        return false;
+    } else if (!this.condition.equals(other.condition))
+      return false;
+    if (this.hitCondition == null) {
+      if (other.hitCondition != null)
+        return false;
+    } else if (!this.hitCondition.equals(other.hitCondition))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.instructionReference== null) ? 0 : this.instructionReference.hashCode());
+    result = prime * result + ((this.offset== null) ? 0 : this.offset.hashCode());
+    result = prime * result + ((this.condition== null) ? 0 : this.condition.hashCode());
+    return prime * result + ((this.hitCondition== null) ? 0 : this.hitCondition.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/InvalidatedAreas.java b/java/org/eclipse/lsp4j/debug/InvalidatedAreas.java
new file mode 100644
index 0000000..a4681f2
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/InvalidatedAreas.java
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+/**
+ * Logical areas that can be invalidated by the 'invalidated' event.
+ * <p>
+ * Possible values include - but not limited to those defined in {@link InvalidatedAreas}
+ */
+@SuppressWarnings("all")
+public interface InvalidatedAreas {
+  /**
+   * All previously fetched data has become invalid and needs to be refetched.
+   */
+  static final String ALL = "all";
+  
+  /**
+   * Previously fetched stack related data has become invalid and needs to be refetched.
+   */
+  static final String STACKS = "stacks";
+  
+  /**
+   * Previously fetched thread related data has become invalid and needs to be refetched.
+   */
+  static final String THREADS = "threads";
+  
+  /**
+   * Previously fetched variable data has become invalid and needs to be refetched.
+   */
+  static final String VARIABLES = "variables";
+}
diff --git a/java/org/eclipse/lsp4j/debug/InvalidatedEventArguments.java b/java/org/eclipse/lsp4j/debug/InvalidatedEventArguments.java
new file mode 100644
index 0000000..9022799
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/InvalidatedEventArguments.java
@@ -0,0 +1,171 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * This event signals that some state in the debug adapter has changed and requires that the client needs to
+ * re-render the data snapshot previously requested.
+ * <p>
+ * Debug adapters do not have to emit this event for runtime changes like stopped or thread events because in that
+ * case the client refetches the new state anyway. But the event can be used for example to refresh the UI after
+ * rendering formatting has changed in the debug adapter.
+ * <p>
+ * This event should only be sent if the debug adapter has received a value true for the
+ * 'supportsInvalidatedEvent' capability of the 'initialize' request.
+ */
+@SuppressWarnings("all")
+public class InvalidatedEventArguments {
+  /**
+   * Optional set of logical areas that got invalidated. This property has a hint characteristic: a client can only
+   * be expected to make a 'best effort' in honouring the areas but there are no guarantees. If this property is
+   * missing, empty, or if values are not understand the client should assume a single value 'all'.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link InvalidatedAreas}
+   */
+  private String[] areas;
+  
+  /**
+   * If specified, the client only needs to refetch data related to this thread.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer threadId;
+  
+  /**
+   * If specified, the client only needs to refetch data related to this stack frame (and the 'threadId' is
+   * ignored).
+   * <p>
+   * This is an optional property.
+   */
+  private Integer stackFrameId;
+  
+  /**
+   * Optional set of logical areas that got invalidated. This property has a hint characteristic: a client can only
+   * be expected to make a 'best effort' in honouring the areas but there are no guarantees. If this property is
+   * missing, empty, or if values are not understand the client should assume a single value 'all'.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link InvalidatedAreas}
+   */
+  @Pure
+  public String[] getAreas() {
+    return this.areas;
+  }
+  
+  /**
+   * Optional set of logical areas that got invalidated. This property has a hint characteristic: a client can only
+   * be expected to make a 'best effort' in honouring the areas but there are no guarantees. If this property is
+   * missing, empty, or if values are not understand the client should assume a single value 'all'.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link InvalidatedAreas}
+   */
+  public void setAreas(final String[] areas) {
+    this.areas = areas;
+  }
+  
+  /**
+   * If specified, the client only needs to refetch data related to this thread.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getThreadId() {
+    return this.threadId;
+  }
+  
+  /**
+   * If specified, the client only needs to refetch data related to this thread.
+   * <p>
+   * This is an optional property.
+   */
+  public void setThreadId(final Integer threadId) {
+    this.threadId = threadId;
+  }
+  
+  /**
+   * If specified, the client only needs to refetch data related to this stack frame (and the 'threadId' is
+   * ignored).
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getStackFrameId() {
+    return this.stackFrameId;
+  }
+  
+  /**
+   * If specified, the client only needs to refetch data related to this stack frame (and the 'threadId' is
+   * ignored).
+   * <p>
+   * This is an optional property.
+   */
+  public void setStackFrameId(final Integer stackFrameId) {
+    this.stackFrameId = stackFrameId;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("areas", this.areas);
+    b.add("threadId", this.threadId);
+    b.add("stackFrameId", this.stackFrameId);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    InvalidatedEventArguments other = (InvalidatedEventArguments) obj;
+    if (this.areas == null) {
+      if (other.areas != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.areas, other.areas))
+      return false;
+    if (this.threadId == null) {
+      if (other.threadId != null)
+        return false;
+    } else if (!this.threadId.equals(other.threadId))
+      return false;
+    if (this.stackFrameId == null) {
+      if (other.stackFrameId != null)
+        return false;
+    } else if (!this.stackFrameId.equals(other.stackFrameId))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.areas== null) ? 0 : Arrays.deepHashCode(this.areas));
+    result = prime * result + ((this.threadId== null) ? 0 : this.threadId.hashCode());
+    return prime * result + ((this.stackFrameId== null) ? 0 : this.stackFrameId.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/LaunchRequestArguments.java b/java/org/eclipse/lsp4j/debug/LaunchRequestArguments.java
new file mode 100644
index 0000000..925b437
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/LaunchRequestArguments.java
@@ -0,0 +1,126 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'launch' request. Additional attributes are implementation specific.
+ */
+@SuppressWarnings("all")
+public class LaunchRequestArguments {
+  /**
+   * If noDebug is true the launch request should launch the program without enabling debugging.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean noDebug;
+  
+  /**
+   * Optional data from the previous, restarted session.
+   * <p>
+   * The data is sent as the 'restart' attribute of the 'terminated' event.
+   * <p>
+   * The client should leave the data intact.
+   * <p>
+   * This is an optional property.
+   */
+  private Object __restart;
+  
+  /**
+   * If noDebug is true the launch request should launch the program without enabling debugging.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getNoDebug() {
+    return this.noDebug;
+  }
+  
+  /**
+   * If noDebug is true the launch request should launch the program without enabling debugging.
+   * <p>
+   * This is an optional property.
+   */
+  public void setNoDebug(final Boolean noDebug) {
+    this.noDebug = noDebug;
+  }
+  
+  /**
+   * Optional data from the previous, restarted session.
+   * <p>
+   * The data is sent as the 'restart' attribute of the 'terminated' event.
+   * <p>
+   * The client should leave the data intact.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Object get__restart() {
+    return this.__restart;
+  }
+  
+  /**
+   * Optional data from the previous, restarted session.
+   * <p>
+   * The data is sent as the 'restart' attribute of the 'terminated' event.
+   * <p>
+   * The client should leave the data intact.
+   * <p>
+   * This is an optional property.
+   */
+  public void set__restart(final Object __restart) {
+    this.__restart = __restart;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("noDebug", this.noDebug);
+    b.add("__restart", this.__restart);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    LaunchRequestArguments other = (LaunchRequestArguments) obj;
+    if (this.noDebug == null) {
+      if (other.noDebug != null)
+        return false;
+    } else if (!this.noDebug.equals(other.noDebug))
+      return false;
+    if (this.__restart == null) {
+      if (other.__restart != null)
+        return false;
+    } else if (!this.__restart.equals(other.__restart))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.noDebug== null) ? 0 : this.noDebug.hashCode());
+    return prime * result + ((this.__restart== null) ? 0 : this.__restart.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/LoadedSourceEventArguments.java b/java/org/eclipse/lsp4j/debug/LoadedSourceEventArguments.java
new file mode 100644
index 0000000..aa9b500
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/LoadedSourceEventArguments.java
@@ -0,0 +1,110 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.LoadedSourceEventArgumentsReason;
+import org.eclipse.lsp4j.debug.Source;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The event indicates that some source has been added, changed, or removed from the set of all loaded sources.
+ */
+@SuppressWarnings("all")
+public class LoadedSourceEventArguments {
+  /**
+   * The reason for the event.
+   */
+  @NonNull
+  private LoadedSourceEventArgumentsReason reason;
+  
+  /**
+   * The new, changed, or removed source.
+   */
+  @NonNull
+  private Source source;
+  
+  /**
+   * The reason for the event.
+   */
+  @Pure
+  @NonNull
+  public LoadedSourceEventArgumentsReason getReason() {
+    return this.reason;
+  }
+  
+  /**
+   * The reason for the event.
+   */
+  public void setReason(@NonNull final LoadedSourceEventArgumentsReason reason) {
+    this.reason = Preconditions.checkNotNull(reason, "reason");
+  }
+  
+  /**
+   * The new, changed, or removed source.
+   */
+  @Pure
+  @NonNull
+  public Source getSource() {
+    return this.source;
+  }
+  
+  /**
+   * The new, changed, or removed source.
+   */
+  public void setSource(@NonNull final Source source) {
+    this.source = Preconditions.checkNotNull(source, "source");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("reason", this.reason);
+    b.add("source", this.source);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    LoadedSourceEventArguments other = (LoadedSourceEventArguments) obj;
+    if (this.reason == null) {
+      if (other.reason != null)
+        return false;
+    } else if (!this.reason.equals(other.reason))
+      return false;
+    if (this.source == null) {
+      if (other.source != null)
+        return false;
+    } else if (!this.source.equals(other.source))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.reason== null) ? 0 : this.reason.hashCode());
+    return prime * result + ((this.source== null) ? 0 : this.source.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/LoadedSourceEventArgumentsReason.java b/java/org/eclipse/lsp4j/debug/LoadedSourceEventArgumentsReason.java
new file mode 100644
index 0000000..2b5fd7b
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/LoadedSourceEventArgumentsReason.java
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+/**
+ * The reason for the event.
+ */
+@SuppressWarnings("all")
+public enum LoadedSourceEventArgumentsReason {
+  NEW,
+  
+  CHANGED,
+  
+  REMOVED;
+}
diff --git a/java/org/eclipse/lsp4j/debug/LoadedSourcesArguments.java b/java/org/eclipse/lsp4j/debug/LoadedSourcesArguments.java
new file mode 100644
index 0000000..0f20af4
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/LoadedSourcesArguments.java
@@ -0,0 +1,46 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'loadedSources' request.
+ */
+@SuppressWarnings("all")
+public class LoadedSourcesArguments {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 1;
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/LoadedSourcesResponse.java b/java/org/eclipse/lsp4j/debug/LoadedSourcesResponse.java
new file mode 100644
index 0000000..bd96e8c
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/LoadedSourcesResponse.java
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.lsp4j.debug.Source;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Response to 'loadedSources' request.
+ */
+@SuppressWarnings("all")
+public class LoadedSourcesResponse {
+  /**
+   * Set of loaded sources.
+   */
+  @NonNull
+  private Source[] sources;
+  
+  /**
+   * Set of loaded sources.
+   */
+  @Pure
+  @NonNull
+  public Source[] getSources() {
+    return this.sources;
+  }
+  
+  /**
+   * Set of loaded sources.
+   */
+  public void setSources(@NonNull final Source[] sources) {
+    this.sources = Preconditions.checkNotNull(sources, "sources");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("sources", this.sources);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    LoadedSourcesResponse other = (LoadedSourcesResponse) obj;
+    if (this.sources == null) {
+      if (other.sources != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.sources, other.sources))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.sources== null) ? 0 : Arrays.deepHashCode(this.sources));
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/Message.java b/java/org/eclipse/lsp4j/debug/Message.java
new file mode 100644
index 0000000..c90ad2f
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/Message.java
@@ -0,0 +1,278 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Map;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A structured message object. Used to return errors from requests.
+ */
+@SuppressWarnings("all")
+public class Message {
+  /**
+   * Unique identifier for the message.
+   */
+  private int id;
+  
+  /**
+   * A format string for the message. Embedded variables have the form '{name}'.
+   * <p>
+   * If variable name starts with an underscore character, the variable does not contain user data (PII) and can be
+   * safely used for telemetry purposes.
+   */
+  @NonNull
+  private String format;
+  
+  /**
+   * An object used as a dictionary for looking up the variables in the format string.
+   * <p>
+   * This is an optional property.
+   */
+  private Map<String, String> variables;
+  
+  /**
+   * If true send to telemetry.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean sendTelemetry;
+  
+  /**
+   * If true show user.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean showUser;
+  
+  /**
+   * An optional url where additional information about this message can be found.
+   * <p>
+   * This is an optional property.
+   */
+  private String url;
+  
+  /**
+   * An optional label that is presented to the user as the UI for opening the url.
+   * <p>
+   * This is an optional property.
+   */
+  private String urlLabel;
+  
+  /**
+   * Unique identifier for the message.
+   */
+  @Pure
+  public int getId() {
+    return this.id;
+  }
+  
+  /**
+   * Unique identifier for the message.
+   */
+  public void setId(final int id) {
+    this.id = id;
+  }
+  
+  /**
+   * A format string for the message. Embedded variables have the form '{name}'.
+   * <p>
+   * If variable name starts with an underscore character, the variable does not contain user data (PII) and can be
+   * safely used for telemetry purposes.
+   */
+  @Pure
+  @NonNull
+  public String getFormat() {
+    return this.format;
+  }
+  
+  /**
+   * A format string for the message. Embedded variables have the form '{name}'.
+   * <p>
+   * If variable name starts with an underscore character, the variable does not contain user data (PII) and can be
+   * safely used for telemetry purposes.
+   */
+  public void setFormat(@NonNull final String format) {
+    this.format = Preconditions.checkNotNull(format, "format");
+  }
+  
+  /**
+   * An object used as a dictionary for looking up the variables in the format string.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Map<String, String> getVariables() {
+    return this.variables;
+  }
+  
+  /**
+   * An object used as a dictionary for looking up the variables in the format string.
+   * <p>
+   * This is an optional property.
+   */
+  public void setVariables(final Map<String, String> variables) {
+    this.variables = variables;
+  }
+  
+  /**
+   * If true send to telemetry.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSendTelemetry() {
+    return this.sendTelemetry;
+  }
+  
+  /**
+   * If true send to telemetry.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSendTelemetry(final Boolean sendTelemetry) {
+    this.sendTelemetry = sendTelemetry;
+  }
+  
+  /**
+   * If true show user.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getShowUser() {
+    return this.showUser;
+  }
+  
+  /**
+   * If true show user.
+   * <p>
+   * This is an optional property.
+   */
+  public void setShowUser(final Boolean showUser) {
+    this.showUser = showUser;
+  }
+  
+  /**
+   * An optional url where additional information about this message can be found.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getUrl() {
+    return this.url;
+  }
+  
+  /**
+   * An optional url where additional information about this message can be found.
+   * <p>
+   * This is an optional property.
+   */
+  public void setUrl(final String url) {
+    this.url = url;
+  }
+  
+  /**
+   * An optional label that is presented to the user as the UI for opening the url.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getUrlLabel() {
+    return this.urlLabel;
+  }
+  
+  /**
+   * An optional label that is presented to the user as the UI for opening the url.
+   * <p>
+   * This is an optional property.
+   */
+  public void setUrlLabel(final String urlLabel) {
+    this.urlLabel = urlLabel;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("id", this.id);
+    b.add("format", this.format);
+    b.add("variables", this.variables);
+    b.add("sendTelemetry", this.sendTelemetry);
+    b.add("showUser", this.showUser);
+    b.add("url", this.url);
+    b.add("urlLabel", this.urlLabel);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    Message other = (Message) obj;
+    if (other.id != this.id)
+      return false;
+    if (this.format == null) {
+      if (other.format != null)
+        return false;
+    } else if (!this.format.equals(other.format))
+      return false;
+    if (this.variables == null) {
+      if (other.variables != null)
+        return false;
+    } else if (!this.variables.equals(other.variables))
+      return false;
+    if (this.sendTelemetry == null) {
+      if (other.sendTelemetry != null)
+        return false;
+    } else if (!this.sendTelemetry.equals(other.sendTelemetry))
+      return false;
+    if (this.showUser == null) {
+      if (other.showUser != null)
+        return false;
+    } else if (!this.showUser.equals(other.showUser))
+      return false;
+    if (this.url == null) {
+      if (other.url != null)
+        return false;
+    } else if (!this.url.equals(other.url))
+      return false;
+    if (this.urlLabel == null) {
+      if (other.urlLabel != null)
+        return false;
+    } else if (!this.urlLabel.equals(other.urlLabel))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + this.id;
+    result = prime * result + ((this.format== null) ? 0 : this.format.hashCode());
+    result = prime * result + ((this.variables== null) ? 0 : this.variables.hashCode());
+    result = prime * result + ((this.sendTelemetry== null) ? 0 : this.sendTelemetry.hashCode());
+    result = prime * result + ((this.showUser== null) ? 0 : this.showUser.hashCode());
+    result = prime * result + ((this.url== null) ? 0 : this.url.hashCode());
+    return prime * result + ((this.urlLabel== null) ? 0 : this.urlLabel.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/Module.java b/java/org/eclipse/lsp4j/debug/Module.java
new file mode 100644
index 0000000..bf93646
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/Module.java
@@ -0,0 +1,432 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A Module object represents a row in the modules view.
+ * <p>
+ * Two attributes are mandatory: an id identifies a module in the modules view and is used in a ModuleEvent for
+ * identifying a module for adding, updating or deleting.
+ * <p>
+ * The name is used to minimally render the module in the UI.
+ * <p>
+ * 
+ * <p>
+ * Additional attributes can be added to the module. They will show up in the module View if they have a
+ * corresponding ColumnDescriptor.
+ * <p>
+ * 
+ * <p>
+ * To avoid an unnecessary proliferation of additional attributes with similar semantics but different names
+ * <p>
+ * we recommend to re-use attributes from the 'recommended' list below first, and only introduce new attributes if
+ * nothing appropriate could be found.
+ */
+@SuppressWarnings("all")
+public class Module {
+  /**
+   * Unique identifier for the module.
+   */
+  @NonNull
+  private Either<Integer, String> id;
+  
+  /**
+   * A name of the module.
+   */
+  @NonNull
+  private String name;
+  
+  /**
+   * optional but recommended attributes.
+   * <p>
+   * always try to use these first before introducing additional attributes.
+   * <p>
+   * 
+   * <p>
+   * Logical full path to the module. The exact definition is implementation defined, but usually this would be a
+   * full path to the on-disk file for the module.
+   * <p>
+   * This is an optional property.
+   */
+  private String path;
+  
+  /**
+   * True if the module is optimized.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean isOptimized;
+  
+  /**
+   * True if the module is considered 'user code' by a debugger that supports 'Just My Code'.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean isUserCode;
+  
+  /**
+   * Version of Module.
+   * <p>
+   * This is an optional property.
+   */
+  private String version;
+  
+  /**
+   * User understandable description of if symbols were found for the module (ex: 'Symbols Loaded', 'Symbols not
+   * found', etc.
+   * <p>
+   * This is an optional property.
+   */
+  private String symbolStatus;
+  
+  /**
+   * Logical full path to the symbol file. The exact definition is implementation defined.
+   * <p>
+   * This is an optional property.
+   */
+  private String symbolFilePath;
+  
+  /**
+   * Module created or modified.
+   * <p>
+   * This is an optional property.
+   */
+  private String dateTimeStamp;
+  
+  /**
+   * Address range covered by this module.
+   * <p>
+   * This is an optional property.
+   */
+  private String addressRange;
+  
+  /**
+   * Unique identifier for the module.
+   */
+  @Pure
+  @NonNull
+  public Either<Integer, String> getId() {
+    return this.id;
+  }
+  
+  /**
+   * Unique identifier for the module.
+   */
+  public void setId(@NonNull final Either<Integer, String> id) {
+    this.id = Preconditions.checkNotNull(id, "id");
+  }
+  
+  public void setId(final Integer id) {
+    if (id == null) {
+      Preconditions.checkNotNull(id, "id");
+      this.id = null;
+      return;
+    }
+    this.id = Either.forLeft(id);
+  }
+  
+  public void setId(final String id) {
+    if (id == null) {
+      Preconditions.checkNotNull(id, "id");
+      this.id = null;
+      return;
+    }
+    this.id = Either.forRight(id);
+  }
+  
+  /**
+   * A name of the module.
+   */
+  @Pure
+  @NonNull
+  public String getName() {
+    return this.name;
+  }
+  
+  /**
+   * A name of the module.
+   */
+  public void setName(@NonNull final String name) {
+    this.name = Preconditions.checkNotNull(name, "name");
+  }
+  
+  /**
+   * optional but recommended attributes.
+   * <p>
+   * always try to use these first before introducing additional attributes.
+   * <p>
+   * 
+   * <p>
+   * Logical full path to the module. The exact definition is implementation defined, but usually this would be a
+   * full path to the on-disk file for the module.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getPath() {
+    return this.path;
+  }
+  
+  /**
+   * optional but recommended attributes.
+   * <p>
+   * always try to use these first before introducing additional attributes.
+   * <p>
+   * 
+   * <p>
+   * Logical full path to the module. The exact definition is implementation defined, but usually this would be a
+   * full path to the on-disk file for the module.
+   * <p>
+   * This is an optional property.
+   */
+  public void setPath(final String path) {
+    this.path = path;
+  }
+  
+  /**
+   * True if the module is optimized.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getIsOptimized() {
+    return this.isOptimized;
+  }
+  
+  /**
+   * True if the module is optimized.
+   * <p>
+   * This is an optional property.
+   */
+  public void setIsOptimized(final Boolean isOptimized) {
+    this.isOptimized = isOptimized;
+  }
+  
+  /**
+   * True if the module is considered 'user code' by a debugger that supports 'Just My Code'.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getIsUserCode() {
+    return this.isUserCode;
+  }
+  
+  /**
+   * True if the module is considered 'user code' by a debugger that supports 'Just My Code'.
+   * <p>
+   * This is an optional property.
+   */
+  public void setIsUserCode(final Boolean isUserCode) {
+    this.isUserCode = isUserCode;
+  }
+  
+  /**
+   * Version of Module.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getVersion() {
+    return this.version;
+  }
+  
+  /**
+   * Version of Module.
+   * <p>
+   * This is an optional property.
+   */
+  public void setVersion(final String version) {
+    this.version = version;
+  }
+  
+  /**
+   * User understandable description of if symbols were found for the module (ex: 'Symbols Loaded', 'Symbols not
+   * found', etc.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getSymbolStatus() {
+    return this.symbolStatus;
+  }
+  
+  /**
+   * User understandable description of if symbols were found for the module (ex: 'Symbols Loaded', 'Symbols not
+   * found', etc.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSymbolStatus(final String symbolStatus) {
+    this.symbolStatus = symbolStatus;
+  }
+  
+  /**
+   * Logical full path to the symbol file. The exact definition is implementation defined.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getSymbolFilePath() {
+    return this.symbolFilePath;
+  }
+  
+  /**
+   * Logical full path to the symbol file. The exact definition is implementation defined.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSymbolFilePath(final String symbolFilePath) {
+    this.symbolFilePath = symbolFilePath;
+  }
+  
+  /**
+   * Module created or modified.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getDateTimeStamp() {
+    return this.dateTimeStamp;
+  }
+  
+  /**
+   * Module created or modified.
+   * <p>
+   * This is an optional property.
+   */
+  public void setDateTimeStamp(final String dateTimeStamp) {
+    this.dateTimeStamp = dateTimeStamp;
+  }
+  
+  /**
+   * Address range covered by this module.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getAddressRange() {
+    return this.addressRange;
+  }
+  
+  /**
+   * Address range covered by this module.
+   * <p>
+   * This is an optional property.
+   */
+  public void setAddressRange(final String addressRange) {
+    this.addressRange = addressRange;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("id", this.id);
+    b.add("name", this.name);
+    b.add("path", this.path);
+    b.add("isOptimized", this.isOptimized);
+    b.add("isUserCode", this.isUserCode);
+    b.add("version", this.version);
+    b.add("symbolStatus", this.symbolStatus);
+    b.add("symbolFilePath", this.symbolFilePath);
+    b.add("dateTimeStamp", this.dateTimeStamp);
+    b.add("addressRange", this.addressRange);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    Module other = (Module) obj;
+    if (this.id == null) {
+      if (other.id != null)
+        return false;
+    } else if (!this.id.equals(other.id))
+      return false;
+    if (this.name == null) {
+      if (other.name != null)
+        return false;
+    } else if (!this.name.equals(other.name))
+      return false;
+    if (this.path == null) {
+      if (other.path != null)
+        return false;
+    } else if (!this.path.equals(other.path))
+      return false;
+    if (this.isOptimized == null) {
+      if (other.isOptimized != null)
+        return false;
+    } else if (!this.isOptimized.equals(other.isOptimized))
+      return false;
+    if (this.isUserCode == null) {
+      if (other.isUserCode != null)
+        return false;
+    } else if (!this.isUserCode.equals(other.isUserCode))
+      return false;
+    if (this.version == null) {
+      if (other.version != null)
+        return false;
+    } else if (!this.version.equals(other.version))
+      return false;
+    if (this.symbolStatus == null) {
+      if (other.symbolStatus != null)
+        return false;
+    } else if (!this.symbolStatus.equals(other.symbolStatus))
+      return false;
+    if (this.symbolFilePath == null) {
+      if (other.symbolFilePath != null)
+        return false;
+    } else if (!this.symbolFilePath.equals(other.symbolFilePath))
+      return false;
+    if (this.dateTimeStamp == null) {
+      if (other.dateTimeStamp != null)
+        return false;
+    } else if (!this.dateTimeStamp.equals(other.dateTimeStamp))
+      return false;
+    if (this.addressRange == null) {
+      if (other.addressRange != null)
+        return false;
+    } else if (!this.addressRange.equals(other.addressRange))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.id== null) ? 0 : this.id.hashCode());
+    result = prime * result + ((this.name== null) ? 0 : this.name.hashCode());
+    result = prime * result + ((this.path== null) ? 0 : this.path.hashCode());
+    result = prime * result + ((this.isOptimized== null) ? 0 : this.isOptimized.hashCode());
+    result = prime * result + ((this.isUserCode== null) ? 0 : this.isUserCode.hashCode());
+    result = prime * result + ((this.version== null) ? 0 : this.version.hashCode());
+    result = prime * result + ((this.symbolStatus== null) ? 0 : this.symbolStatus.hashCode());
+    result = prime * result + ((this.symbolFilePath== null) ? 0 : this.symbolFilePath.hashCode());
+    result = prime * result + ((this.dateTimeStamp== null) ? 0 : this.dateTimeStamp.hashCode());
+    return prime * result + ((this.addressRange== null) ? 0 : this.addressRange.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ModuleEventArguments.java b/java/org/eclipse/lsp4j/debug/ModuleEventArguments.java
new file mode 100644
index 0000000..97005d3
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ModuleEventArguments.java
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.ModuleEventArgumentsReason;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The event indicates that some information about a module has changed.
+ */
+@SuppressWarnings("all")
+public class ModuleEventArguments {
+  /**
+   * The reason for the event.
+   */
+  @NonNull
+  private ModuleEventArgumentsReason reason;
+  
+  /**
+   * The new, changed, or removed module. In case of 'removed' only the module id is used.
+   */
+  @NonNull
+  private org.eclipse.lsp4j.debug.Module module;
+  
+  /**
+   * The reason for the event.
+   */
+  @Pure
+  @NonNull
+  public ModuleEventArgumentsReason getReason() {
+    return this.reason;
+  }
+  
+  /**
+   * The reason for the event.
+   */
+  public void setReason(@NonNull final ModuleEventArgumentsReason reason) {
+    this.reason = Preconditions.checkNotNull(reason, "reason");
+  }
+  
+  /**
+   * The new, changed, or removed module. In case of 'removed' only the module id is used.
+   */
+  @Pure
+  @NonNull
+  public org.eclipse.lsp4j.debug.Module getModule() {
+    return this.module;
+  }
+  
+  /**
+   * The new, changed, or removed module. In case of 'removed' only the module id is used.
+   */
+  public void setModule(@NonNull final org.eclipse.lsp4j.debug.Module module) {
+    this.module = Preconditions.checkNotNull(module, "module");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("reason", this.reason);
+    b.add("module", this.module);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ModuleEventArguments other = (ModuleEventArguments) obj;
+    if (this.reason == null) {
+      if (other.reason != null)
+        return false;
+    } else if (!this.reason.equals(other.reason))
+      return false;
+    if (this.module == null) {
+      if (other.module != null)
+        return false;
+    } else if (!this.module.equals(other.module))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.reason== null) ? 0 : this.reason.hashCode());
+    return prime * result + ((this.module== null) ? 0 : this.module.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ModuleEventArgumentsReason.java b/java/org/eclipse/lsp4j/debug/ModuleEventArgumentsReason.java
new file mode 100644
index 0000000..b328e26
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ModuleEventArgumentsReason.java
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+/**
+ * The reason for the event.
+ */
+@SuppressWarnings("all")
+public enum ModuleEventArgumentsReason {
+  NEW,
+  
+  CHANGED,
+  
+  REMOVED;
+}
diff --git a/java/org/eclipse/lsp4j/debug/ModulesArguments.java b/java/org/eclipse/lsp4j/debug/ModulesArguments.java
new file mode 100644
index 0000000..37a4f36
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ModulesArguments.java
@@ -0,0 +1,114 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'modules' request.
+ */
+@SuppressWarnings("all")
+public class ModulesArguments {
+  /**
+   * The index of the first module to return; if omitted modules start at 0.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer startModule;
+  
+  /**
+   * The number of modules to return. If moduleCount is not specified or 0, all modules are returned.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer moduleCount;
+  
+  /**
+   * The index of the first module to return; if omitted modules start at 0.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getStartModule() {
+    return this.startModule;
+  }
+  
+  /**
+   * The index of the first module to return; if omitted modules start at 0.
+   * <p>
+   * This is an optional property.
+   */
+  public void setStartModule(final Integer startModule) {
+    this.startModule = startModule;
+  }
+  
+  /**
+   * The number of modules to return. If moduleCount is not specified or 0, all modules are returned.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getModuleCount() {
+    return this.moduleCount;
+  }
+  
+  /**
+   * The number of modules to return. If moduleCount is not specified or 0, all modules are returned.
+   * <p>
+   * This is an optional property.
+   */
+  public void setModuleCount(final Integer moduleCount) {
+    this.moduleCount = moduleCount;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("startModule", this.startModule);
+    b.add("moduleCount", this.moduleCount);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ModulesArguments other = (ModulesArguments) obj;
+    if (this.startModule == null) {
+      if (other.startModule != null)
+        return false;
+    } else if (!this.startModule.equals(other.startModule))
+      return false;
+    if (this.moduleCount == null) {
+      if (other.moduleCount != null)
+        return false;
+    } else if (!this.moduleCount.equals(other.moduleCount))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.startModule== null) ? 0 : this.startModule.hashCode());
+    return prime * result + ((this.moduleCount== null) ? 0 : this.moduleCount.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ModulesResponse.java b/java/org/eclipse/lsp4j/debug/ModulesResponse.java
new file mode 100644
index 0000000..bf2df1d
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ModulesResponse.java
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Response to 'modules' request.
+ */
+@SuppressWarnings("all")
+public class ModulesResponse {
+  /**
+   * All modules or range of modules.
+   */
+  @NonNull
+  private org.eclipse.lsp4j.debug.Module[] modules;
+  
+  /**
+   * The total number of modules available.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer totalModules;
+  
+  /**
+   * All modules or range of modules.
+   */
+  @Pure
+  @NonNull
+  public org.eclipse.lsp4j.debug.Module[] getModules() {
+    return this.modules;
+  }
+  
+  /**
+   * All modules or range of modules.
+   */
+  public void setModules(@NonNull final org.eclipse.lsp4j.debug.Module[] modules) {
+    this.modules = Preconditions.checkNotNull(modules, "modules");
+  }
+  
+  /**
+   * The total number of modules available.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getTotalModules() {
+    return this.totalModules;
+  }
+  
+  /**
+   * The total number of modules available.
+   * <p>
+   * This is an optional property.
+   */
+  public void setTotalModules(final Integer totalModules) {
+    this.totalModules = totalModules;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("modules", this.modules);
+    b.add("totalModules", this.totalModules);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ModulesResponse other = (ModulesResponse) obj;
+    if (this.modules == null) {
+      if (other.modules != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.modules, other.modules))
+      return false;
+    if (this.totalModules == null) {
+      if (other.totalModules != null)
+        return false;
+    } else if (!this.totalModules.equals(other.totalModules))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.modules== null) ? 0 : Arrays.deepHashCode(this.modules));
+    return prime * result + ((this.totalModules== null) ? 0 : this.totalModules.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ModulesViewDescriptor.java b/java/org/eclipse/lsp4j/debug/ModulesViewDescriptor.java
new file mode 100644
index 0000000..42e30ce
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ModulesViewDescriptor.java
@@ -0,0 +1,72 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.lsp4j.debug.ColumnDescriptor;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The ModulesViewDescriptor is the container for all declarative configuration options of a ModuleView.
+ * <p>
+ * For now it only specifies the columns to be shown in the modules view.
+ */
+@SuppressWarnings("all")
+public class ModulesViewDescriptor {
+  @NonNull
+  private ColumnDescriptor[] columns;
+  
+  @Pure
+  @NonNull
+  public ColumnDescriptor[] getColumns() {
+    return this.columns;
+  }
+  
+  public void setColumns(@NonNull final ColumnDescriptor[] columns) {
+    this.columns = Preconditions.checkNotNull(columns, "columns");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("columns", this.columns);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ModulesViewDescriptor other = (ModulesViewDescriptor) obj;
+    if (this.columns == null) {
+      if (other.columns != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.columns, other.columns))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.columns== null) ? 0 : Arrays.deepHashCode(this.columns));
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/NextArguments.java b/java/org/eclipse/lsp4j/debug/NextArguments.java
new file mode 100644
index 0000000..61964fc
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/NextArguments.java
@@ -0,0 +1,106 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.SteppingGranularity;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'next' request.
+ */
+@SuppressWarnings("all")
+public class NextArguments {
+  /**
+   * Execute 'next' for this thread.
+   */
+  private int threadId;
+  
+  /**
+   * Optional granularity to step. If no granularity is specified, a granularity of 'statement' is assumed.
+   * <p>
+   * This is an optional property.
+   */
+  private SteppingGranularity granularity;
+  
+  /**
+   * Execute 'next' for this thread.
+   */
+  @Pure
+  public int getThreadId() {
+    return this.threadId;
+  }
+  
+  /**
+   * Execute 'next' for this thread.
+   */
+  public void setThreadId(final int threadId) {
+    this.threadId = threadId;
+  }
+  
+  /**
+   * Optional granularity to step. If no granularity is specified, a granularity of 'statement' is assumed.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public SteppingGranularity getGranularity() {
+    return this.granularity;
+  }
+  
+  /**
+   * Optional granularity to step. If no granularity is specified, a granularity of 'statement' is assumed.
+   * <p>
+   * This is an optional property.
+   */
+  public void setGranularity(final SteppingGranularity granularity) {
+    this.granularity = granularity;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("threadId", this.threadId);
+    b.add("granularity", this.granularity);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    NextArguments other = (NextArguments) obj;
+    if (other.threadId != this.threadId)
+      return false;
+    if (this.granularity == null) {
+      if (other.granularity != null)
+        return false;
+    } else if (!this.granularity.equals(other.granularity))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + this.threadId;
+    return prime * result + ((this.granularity== null) ? 0 : this.granularity.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/OutputEventArguments.java b/java/org/eclipse/lsp4j/debug/OutputEventArguments.java
new file mode 100644
index 0000000..5f70a0d
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/OutputEventArguments.java
@@ -0,0 +1,327 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.OutputEventArgumentsGroup;
+import org.eclipse.lsp4j.debug.Source;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The event indicates that the target has produced some output.
+ */
+@SuppressWarnings("all")
+public class OutputEventArguments {
+  /**
+   * The output category. If not specified, 'console' is assumed.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link OutputEventArgumentsCategory}
+   */
+  private String category;
+  
+  /**
+   * The output to report.
+   */
+  @NonNull
+  private String output;
+  
+  /**
+   * Support for keeping an output log organized by grouping related messages.
+   * <p>
+   * This is an optional property.
+   */
+  private OutputEventArgumentsGroup group;
+  
+  /**
+   * If an attribute 'variablesReference' exists and its value is &gt; 0, the output contains objects which can be
+   * retrieved by passing 'variablesReference' to the 'variables' request. The value should be less than or equal to
+   * 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  private Integer variablesReference;
+  
+  /**
+   * An optional source location where the output was produced.
+   * <p>
+   * This is an optional property.
+   */
+  private Source source;
+  
+  /**
+   * An optional source location line where the output was produced.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer line;
+  
+  /**
+   * An optional source location column where the output was produced.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer column;
+  
+  /**
+   * Optional data to report. For the 'telemetry' category the data will be sent to telemetry, for the other
+   * categories the data is shown in JSON format.
+   * <p>
+   * This is an optional property.
+   */
+  private Object data;
+  
+  /**
+   * The output category. If not specified, 'console' is assumed.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link OutputEventArgumentsCategory}
+   */
+  @Pure
+  public String getCategory() {
+    return this.category;
+  }
+  
+  /**
+   * The output category. If not specified, 'console' is assumed.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link OutputEventArgumentsCategory}
+   */
+  public void setCategory(final String category) {
+    this.category = category;
+  }
+  
+  /**
+   * The output to report.
+   */
+  @Pure
+  @NonNull
+  public String getOutput() {
+    return this.output;
+  }
+  
+  /**
+   * The output to report.
+   */
+  public void setOutput(@NonNull final String output) {
+    this.output = Preconditions.checkNotNull(output, "output");
+  }
+  
+  /**
+   * Support for keeping an output log organized by grouping related messages.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public OutputEventArgumentsGroup getGroup() {
+    return this.group;
+  }
+  
+  /**
+   * Support for keeping an output log organized by grouping related messages.
+   * <p>
+   * This is an optional property.
+   */
+  public void setGroup(final OutputEventArgumentsGroup group) {
+    this.group = group;
+  }
+  
+  /**
+   * If an attribute 'variablesReference' exists and its value is &gt; 0, the output contains objects which can be
+   * retrieved by passing 'variablesReference' to the 'variables' request. The value should be less than or equal to
+   * 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getVariablesReference() {
+    return this.variablesReference;
+  }
+  
+  /**
+   * If an attribute 'variablesReference' exists and its value is &gt; 0, the output contains objects which can be
+   * retrieved by passing 'variablesReference' to the 'variables' request. The value should be less than or equal to
+   * 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  public void setVariablesReference(final Integer variablesReference) {
+    this.variablesReference = variablesReference;
+  }
+  
+  /**
+   * An optional source location where the output was produced.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Source getSource() {
+    return this.source;
+  }
+  
+  /**
+   * An optional source location where the output was produced.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSource(final Source source) {
+    this.source = source;
+  }
+  
+  /**
+   * An optional source location line where the output was produced.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getLine() {
+    return this.line;
+  }
+  
+  /**
+   * An optional source location line where the output was produced.
+   * <p>
+   * This is an optional property.
+   */
+  public void setLine(final Integer line) {
+    this.line = line;
+  }
+  
+  /**
+   * An optional source location column where the output was produced.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getColumn() {
+    return this.column;
+  }
+  
+  /**
+   * An optional source location column where the output was produced.
+   * <p>
+   * This is an optional property.
+   */
+  public void setColumn(final Integer column) {
+    this.column = column;
+  }
+  
+  /**
+   * Optional data to report. For the 'telemetry' category the data will be sent to telemetry, for the other
+   * categories the data is shown in JSON format.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Object getData() {
+    return this.data;
+  }
+  
+  /**
+   * Optional data to report. For the 'telemetry' category the data will be sent to telemetry, for the other
+   * categories the data is shown in JSON format.
+   * <p>
+   * This is an optional property.
+   */
+  public void setData(final Object data) {
+    this.data = data;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("category", this.category);
+    b.add("output", this.output);
+    b.add("group", this.group);
+    b.add("variablesReference", this.variablesReference);
+    b.add("source", this.source);
+    b.add("line", this.line);
+    b.add("column", this.column);
+    b.add("data", this.data);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    OutputEventArguments other = (OutputEventArguments) obj;
+    if (this.category == null) {
+      if (other.category != null)
+        return false;
+    } else if (!this.category.equals(other.category))
+      return false;
+    if (this.output == null) {
+      if (other.output != null)
+        return false;
+    } else if (!this.output.equals(other.output))
+      return false;
+    if (this.group == null) {
+      if (other.group != null)
+        return false;
+    } else if (!this.group.equals(other.group))
+      return false;
+    if (this.variablesReference == null) {
+      if (other.variablesReference != null)
+        return false;
+    } else if (!this.variablesReference.equals(other.variablesReference))
+      return false;
+    if (this.source == null) {
+      if (other.source != null)
+        return false;
+    } else if (!this.source.equals(other.source))
+      return false;
+    if (this.line == null) {
+      if (other.line != null)
+        return false;
+    } else if (!this.line.equals(other.line))
+      return false;
+    if (this.column == null) {
+      if (other.column != null)
+        return false;
+    } else if (!this.column.equals(other.column))
+      return false;
+    if (this.data == null) {
+      if (other.data != null)
+        return false;
+    } else if (!this.data.equals(other.data))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.category== null) ? 0 : this.category.hashCode());
+    result = prime * result + ((this.output== null) ? 0 : this.output.hashCode());
+    result = prime * result + ((this.group== null) ? 0 : this.group.hashCode());
+    result = prime * result + ((this.variablesReference== null) ? 0 : this.variablesReference.hashCode());
+    result = prime * result + ((this.source== null) ? 0 : this.source.hashCode());
+    result = prime * result + ((this.line== null) ? 0 : this.line.hashCode());
+    result = prime * result + ((this.column== null) ? 0 : this.column.hashCode());
+    return prime * result + ((this.data== null) ? 0 : this.data.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/OutputEventArgumentsCategory.java b/java/org/eclipse/lsp4j/debug/OutputEventArgumentsCategory.java
new file mode 100644
index 0000000..37bfa73
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/OutputEventArgumentsCategory.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+/**
+ * The output category. If not specified, 'console' is assumed.
+ * <p>
+ * Possible values include - but not limited to those defined in {@link OutputEventArgumentsCategory}
+ */
+@SuppressWarnings("all")
+public interface OutputEventArgumentsCategory {
+  static final String CONSOLE = "console";
+  
+  static final String STDOUT = "stdout";
+  
+  static final String STDERR = "stderr";
+  
+  static final String TELEMETRY = "telemetry";
+}
diff --git a/java/org/eclipse/lsp4j/debug/OutputEventArgumentsGroup.java b/java/org/eclipse/lsp4j/debug/OutputEventArgumentsGroup.java
new file mode 100644
index 0000000..226ce54
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/OutputEventArgumentsGroup.java
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+/**
+ * Support for keeping an output log organized by grouping related messages.
+ */
+@SuppressWarnings("all")
+public enum OutputEventArgumentsGroup {
+  /**
+   * Start a new group in expanded mode. Subsequent output events are members of the group and should be shown
+   * indented.
+   * The 'output' attribute becomes the name of the group and is not indented.
+   */
+  START,
+  
+  /**
+   * Start a new group in collapsed mode. Subsequent output events are members of the group and should be shown
+   * indented (as soon as the group is expanded).
+   * The 'output' attribute becomes the name of the group and is not
+   * indented.
+   */
+  START_COLLAPSED,
+  
+  /**
+   * End the current group and decreases the indentation of subsequent output events.
+   * A non empty 'output' attribute
+   * is shown as the unindented end of the group.
+   */
+  END;
+}
diff --git a/java/org/eclipse/lsp4j/debug/PauseArguments.java b/java/org/eclipse/lsp4j/debug/PauseArguments.java
new file mode 100644
index 0000000..db07728
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/PauseArguments.java
@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'pause' request.
+ */
+@SuppressWarnings("all")
+public class PauseArguments {
+  /**
+   * Pause execution for this thread.
+   */
+  private int threadId;
+  
+  /**
+   * Pause execution for this thread.
+   */
+  @Pure
+  public int getThreadId() {
+    return this.threadId;
+  }
+  
+  /**
+   * Pause execution for this thread.
+   */
+  public void setThreadId(final int threadId) {
+    this.threadId = threadId;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("threadId", this.threadId);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    PauseArguments other = (PauseArguments) obj;
+    if (other.threadId != this.threadId)
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + this.threadId;
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ProcessEventArguments.java b/java/org/eclipse/lsp4j/debug/ProcessEventArguments.java
new file mode 100644
index 0000000..da87ede
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ProcessEventArguments.java
@@ -0,0 +1,219 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.ProcessEventArgumentsStartMethod;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The event indicates that the debugger has begun debugging a new process. Either one that it has launched, or
+ * one that it has attached to.
+ */
+@SuppressWarnings("all")
+public class ProcessEventArguments {
+  /**
+   * The logical name of the process. This is usually the full path to process's executable file. Example:
+   * /home/example/myproj/program.js.
+   */
+  @NonNull
+  private String name;
+  
+  /**
+   * The system process id of the debugged process. This property will be missing for non-system processes.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer systemProcessId;
+  
+  /**
+   * If true, the process is running on the same computer as the debug adapter.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean isLocalProcess;
+  
+  /**
+   * Describes how the debug engine started debugging this process.
+   * <p>
+   * This is an optional property.
+   */
+  private ProcessEventArgumentsStartMethod startMethod;
+  
+  /**
+   * The size of a pointer or address for this process, in bits. This value may be used by clients when formatting
+   * addresses for display.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer pointerSize;
+  
+  /**
+   * The logical name of the process. This is usually the full path to process's executable file. Example:
+   * /home/example/myproj/program.js.
+   */
+  @Pure
+  @NonNull
+  public String getName() {
+    return this.name;
+  }
+  
+  /**
+   * The logical name of the process. This is usually the full path to process's executable file. Example:
+   * /home/example/myproj/program.js.
+   */
+  public void setName(@NonNull final String name) {
+    this.name = Preconditions.checkNotNull(name, "name");
+  }
+  
+  /**
+   * The system process id of the debugged process. This property will be missing for non-system processes.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getSystemProcessId() {
+    return this.systemProcessId;
+  }
+  
+  /**
+   * The system process id of the debugged process. This property will be missing for non-system processes.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSystemProcessId(final Integer systemProcessId) {
+    this.systemProcessId = systemProcessId;
+  }
+  
+  /**
+   * If true, the process is running on the same computer as the debug adapter.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getIsLocalProcess() {
+    return this.isLocalProcess;
+  }
+  
+  /**
+   * If true, the process is running on the same computer as the debug adapter.
+   * <p>
+   * This is an optional property.
+   */
+  public void setIsLocalProcess(final Boolean isLocalProcess) {
+    this.isLocalProcess = isLocalProcess;
+  }
+  
+  /**
+   * Describes how the debug engine started debugging this process.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public ProcessEventArgumentsStartMethod getStartMethod() {
+    return this.startMethod;
+  }
+  
+  /**
+   * Describes how the debug engine started debugging this process.
+   * <p>
+   * This is an optional property.
+   */
+  public void setStartMethod(final ProcessEventArgumentsStartMethod startMethod) {
+    this.startMethod = startMethod;
+  }
+  
+  /**
+   * The size of a pointer or address for this process, in bits. This value may be used by clients when formatting
+   * addresses for display.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getPointerSize() {
+    return this.pointerSize;
+  }
+  
+  /**
+   * The size of a pointer or address for this process, in bits. This value may be used by clients when formatting
+   * addresses for display.
+   * <p>
+   * This is an optional property.
+   */
+  public void setPointerSize(final Integer pointerSize) {
+    this.pointerSize = pointerSize;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("name", this.name);
+    b.add("systemProcessId", this.systemProcessId);
+    b.add("isLocalProcess", this.isLocalProcess);
+    b.add("startMethod", this.startMethod);
+    b.add("pointerSize", this.pointerSize);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ProcessEventArguments other = (ProcessEventArguments) obj;
+    if (this.name == null) {
+      if (other.name != null)
+        return false;
+    } else if (!this.name.equals(other.name))
+      return false;
+    if (this.systemProcessId == null) {
+      if (other.systemProcessId != null)
+        return false;
+    } else if (!this.systemProcessId.equals(other.systemProcessId))
+      return false;
+    if (this.isLocalProcess == null) {
+      if (other.isLocalProcess != null)
+        return false;
+    } else if (!this.isLocalProcess.equals(other.isLocalProcess))
+      return false;
+    if (this.startMethod == null) {
+      if (other.startMethod != null)
+        return false;
+    } else if (!this.startMethod.equals(other.startMethod))
+      return false;
+    if (this.pointerSize == null) {
+      if (other.pointerSize != null)
+        return false;
+    } else if (!this.pointerSize.equals(other.pointerSize))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.name== null) ? 0 : this.name.hashCode());
+    result = prime * result + ((this.systemProcessId== null) ? 0 : this.systemProcessId.hashCode());
+    result = prime * result + ((this.isLocalProcess== null) ? 0 : this.isLocalProcess.hashCode());
+    result = prime * result + ((this.startMethod== null) ? 0 : this.startMethod.hashCode());
+    return prime * result + ((this.pointerSize== null) ? 0 : this.pointerSize.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ProcessEventArgumentsStartMethod.java b/java/org/eclipse/lsp4j/debug/ProcessEventArgumentsStartMethod.java
new file mode 100644
index 0000000..c25fe11
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ProcessEventArgumentsStartMethod.java
@@ -0,0 +1,34 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+/**
+ * Describes how the debug engine started debugging this process.
+ */
+@SuppressWarnings("all")
+public enum ProcessEventArgumentsStartMethod {
+  /**
+   * Process was launched under the debugger.
+   */
+  LAUNCH,
+  
+  /**
+   * Debugger attached to an existing process.
+   */
+  ATTACH,
+  
+  /**
+   * A project launcher component has launched a new process in a suspended state and then asked the debugger to
+   * attach.
+   */
+  ATTACH_FOR_SUSPENDED_LAUNCH;
+}
diff --git a/java/org/eclipse/lsp4j/debug/ProgressEndEventArguments.java b/java/org/eclipse/lsp4j/debug/ProgressEndEventArguments.java
new file mode 100644
index 0000000..db29beb
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ProgressEndEventArguments.java
@@ -0,0 +1,115 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The event signals the end of the progress reporting with an optional final message.
+ * <p>
+ * This event should only be sent if the client has passed the value true for the 'supportsProgressReporting'
+ * capability of the 'initialize' request.
+ */
+@SuppressWarnings("all")
+public class ProgressEndEventArguments {
+  /**
+   * The ID that was introduced in the initial 'ProgressStartEvent'.
+   */
+  @NonNull
+  private String progressId;
+  
+  /**
+   * Optional, more detailed progress message. If omitted, the previous message (if any) is used.
+   * <p>
+   * This is an optional property.
+   */
+  private String message;
+  
+  /**
+   * The ID that was introduced in the initial 'ProgressStartEvent'.
+   */
+  @Pure
+  @NonNull
+  public String getProgressId() {
+    return this.progressId;
+  }
+  
+  /**
+   * The ID that was introduced in the initial 'ProgressStartEvent'.
+   */
+  public void setProgressId(@NonNull final String progressId) {
+    this.progressId = Preconditions.checkNotNull(progressId, "progressId");
+  }
+  
+  /**
+   * Optional, more detailed progress message. If omitted, the previous message (if any) is used.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getMessage() {
+    return this.message;
+  }
+  
+  /**
+   * Optional, more detailed progress message. If omitted, the previous message (if any) is used.
+   * <p>
+   * This is an optional property.
+   */
+  public void setMessage(final String message) {
+    this.message = message;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("progressId", this.progressId);
+    b.add("message", this.message);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ProgressEndEventArguments other = (ProgressEndEventArguments) obj;
+    if (this.progressId == null) {
+      if (other.progressId != null)
+        return false;
+    } else if (!this.progressId.equals(other.progressId))
+      return false;
+    if (this.message == null) {
+      if (other.message != null)
+        return false;
+    } else if (!this.message.equals(other.message))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.progressId== null) ? 0 : this.progressId.hashCode());
+    return prime * result + ((this.message== null) ? 0 : this.message.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ProgressStartEventArguments.java b/java/org/eclipse/lsp4j/debug/ProgressStartEventArguments.java
new file mode 100644
index 0000000..b5cf28a
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ProgressStartEventArguments.java
@@ -0,0 +1,283 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The event signals that a long running operation is about to start and
+ * <p>
+ * provides additional information for the client to set up a corresponding progress and cancellation UI.
+ * <p>
+ * The client is free to delay the showing of the UI in order to reduce flicker.
+ * <p>
+ * This event should only be sent if the client has passed the value true for the 'supportsProgressReporting'
+ * capability of the 'initialize' request.
+ */
+@SuppressWarnings("all")
+public class ProgressStartEventArguments {
+  /**
+   * An ID that must be used in subsequent 'progressUpdate' and 'progressEnd' events to make them refer to the same
+   * progress reporting.
+   * <p>
+   * IDs must be unique within a debug session.
+   */
+  @NonNull
+  private String progressId;
+  
+  /**
+   * Mandatory (short) title of the progress reporting. Shown in the UI to describe the long running operation.
+   */
+  @NonNull
+  private String title;
+  
+  /**
+   * The request ID that this progress report is related to. If specified a debug adapter is expected to emit
+   * <p>
+   * progress events for the long running request until the request has been either completed or cancelled.
+   * <p>
+   * If the request ID is omitted, the progress report is assumed to be related to some general activity of the
+   * debug adapter.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer requestId;
+  
+  /**
+   * If true, the request that reports progress may be canceled with a 'cancel' request.
+   * <p>
+   * So this property basically controls whether the client should use UX that supports cancellation.
+   * <p>
+   * Clients that don't support cancellation are allowed to ignore the setting.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean cancellable;
+  
+  /**
+   * Optional, more detailed progress message.
+   * <p>
+   * This is an optional property.
+   */
+  private String message;
+  
+  /**
+   * Optional progress percentage to display (value range: 0 to 100). If omitted no percentage will be shown.
+   * <p>
+   * This is an optional property.
+   */
+  private Double percentage;
+  
+  /**
+   * An ID that must be used in subsequent 'progressUpdate' and 'progressEnd' events to make them refer to the same
+   * progress reporting.
+   * <p>
+   * IDs must be unique within a debug session.
+   */
+  @Pure
+  @NonNull
+  public String getProgressId() {
+    return this.progressId;
+  }
+  
+  /**
+   * An ID that must be used in subsequent 'progressUpdate' and 'progressEnd' events to make them refer to the same
+   * progress reporting.
+   * <p>
+   * IDs must be unique within a debug session.
+   */
+  public void setProgressId(@NonNull final String progressId) {
+    this.progressId = Preconditions.checkNotNull(progressId, "progressId");
+  }
+  
+  /**
+   * Mandatory (short) title of the progress reporting. Shown in the UI to describe the long running operation.
+   */
+  @Pure
+  @NonNull
+  public String getTitle() {
+    return this.title;
+  }
+  
+  /**
+   * Mandatory (short) title of the progress reporting. Shown in the UI to describe the long running operation.
+   */
+  public void setTitle(@NonNull final String title) {
+    this.title = Preconditions.checkNotNull(title, "title");
+  }
+  
+  /**
+   * The request ID that this progress report is related to. If specified a debug adapter is expected to emit
+   * <p>
+   * progress events for the long running request until the request has been either completed or cancelled.
+   * <p>
+   * If the request ID is omitted, the progress report is assumed to be related to some general activity of the
+   * debug adapter.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getRequestId() {
+    return this.requestId;
+  }
+  
+  /**
+   * The request ID that this progress report is related to. If specified a debug adapter is expected to emit
+   * <p>
+   * progress events for the long running request until the request has been either completed or cancelled.
+   * <p>
+   * If the request ID is omitted, the progress report is assumed to be related to some general activity of the
+   * debug adapter.
+   * <p>
+   * This is an optional property.
+   */
+  public void setRequestId(final Integer requestId) {
+    this.requestId = requestId;
+  }
+  
+  /**
+   * If true, the request that reports progress may be canceled with a 'cancel' request.
+   * <p>
+   * So this property basically controls whether the client should use UX that supports cancellation.
+   * <p>
+   * Clients that don't support cancellation are allowed to ignore the setting.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getCancellable() {
+    return this.cancellable;
+  }
+  
+  /**
+   * If true, the request that reports progress may be canceled with a 'cancel' request.
+   * <p>
+   * So this property basically controls whether the client should use UX that supports cancellation.
+   * <p>
+   * Clients that don't support cancellation are allowed to ignore the setting.
+   * <p>
+   * This is an optional property.
+   */
+  public void setCancellable(final Boolean cancellable) {
+    this.cancellable = cancellable;
+  }
+  
+  /**
+   * Optional, more detailed progress message.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getMessage() {
+    return this.message;
+  }
+  
+  /**
+   * Optional, more detailed progress message.
+   * <p>
+   * This is an optional property.
+   */
+  public void setMessage(final String message) {
+    this.message = message;
+  }
+  
+  /**
+   * Optional progress percentage to display (value range: 0 to 100). If omitted no percentage will be shown.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Double getPercentage() {
+    return this.percentage;
+  }
+  
+  /**
+   * Optional progress percentage to display (value range: 0 to 100). If omitted no percentage will be shown.
+   * <p>
+   * This is an optional property.
+   */
+  public void setPercentage(final Double percentage) {
+    this.percentage = percentage;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("progressId", this.progressId);
+    b.add("title", this.title);
+    b.add("requestId", this.requestId);
+    b.add("cancellable", this.cancellable);
+    b.add("message", this.message);
+    b.add("percentage", this.percentage);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ProgressStartEventArguments other = (ProgressStartEventArguments) obj;
+    if (this.progressId == null) {
+      if (other.progressId != null)
+        return false;
+    } else if (!this.progressId.equals(other.progressId))
+      return false;
+    if (this.title == null) {
+      if (other.title != null)
+        return false;
+    } else if (!this.title.equals(other.title))
+      return false;
+    if (this.requestId == null) {
+      if (other.requestId != null)
+        return false;
+    } else if (!this.requestId.equals(other.requestId))
+      return false;
+    if (this.cancellable == null) {
+      if (other.cancellable != null)
+        return false;
+    } else if (!this.cancellable.equals(other.cancellable))
+      return false;
+    if (this.message == null) {
+      if (other.message != null)
+        return false;
+    } else if (!this.message.equals(other.message))
+      return false;
+    if (this.percentage == null) {
+      if (other.percentage != null)
+        return false;
+    } else if (!this.percentage.equals(other.percentage))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.progressId== null) ? 0 : this.progressId.hashCode());
+    result = prime * result + ((this.title== null) ? 0 : this.title.hashCode());
+    result = prime * result + ((this.requestId== null) ? 0 : this.requestId.hashCode());
+    result = prime * result + ((this.cancellable== null) ? 0 : this.cancellable.hashCode());
+    result = prime * result + ((this.message== null) ? 0 : this.message.hashCode());
+    return prime * result + ((this.percentage== null) ? 0 : this.percentage.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ProgressUpdateEventArguments.java b/java/org/eclipse/lsp4j/debug/ProgressUpdateEventArguments.java
new file mode 100644
index 0000000..24f819b
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ProgressUpdateEventArguments.java
@@ -0,0 +1,151 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The event signals that the progress reporting needs to updated with a new message and/or percentage.
+ * <p>
+ * The client does not have to update the UI immediately, but the clients needs to keep track of the message
+ * and/or percentage values.
+ * <p>
+ * This event should only be sent if the client has passed the value true for the 'supportsProgressReporting'
+ * capability of the 'initialize' request.
+ */
+@SuppressWarnings("all")
+public class ProgressUpdateEventArguments {
+  /**
+   * The ID that was introduced in the initial 'progressStart' event.
+   */
+  @NonNull
+  private String progressId;
+  
+  /**
+   * Optional, more detailed progress message. If omitted, the previous message (if any) is used.
+   * <p>
+   * This is an optional property.
+   */
+  private String message;
+  
+  /**
+   * Optional progress percentage to display (value range: 0 to 100). If omitted no percentage will be shown.
+   * <p>
+   * This is an optional property.
+   */
+  private Double percentage;
+  
+  /**
+   * The ID that was introduced in the initial 'progressStart' event.
+   */
+  @Pure
+  @NonNull
+  public String getProgressId() {
+    return this.progressId;
+  }
+  
+  /**
+   * The ID that was introduced in the initial 'progressStart' event.
+   */
+  public void setProgressId(@NonNull final String progressId) {
+    this.progressId = Preconditions.checkNotNull(progressId, "progressId");
+  }
+  
+  /**
+   * Optional, more detailed progress message. If omitted, the previous message (if any) is used.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getMessage() {
+    return this.message;
+  }
+  
+  /**
+   * Optional, more detailed progress message. If omitted, the previous message (if any) is used.
+   * <p>
+   * This is an optional property.
+   */
+  public void setMessage(final String message) {
+    this.message = message;
+  }
+  
+  /**
+   * Optional progress percentage to display (value range: 0 to 100). If omitted no percentage will be shown.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Double getPercentage() {
+    return this.percentage;
+  }
+  
+  /**
+   * Optional progress percentage to display (value range: 0 to 100). If omitted no percentage will be shown.
+   * <p>
+   * This is an optional property.
+   */
+  public void setPercentage(final Double percentage) {
+    this.percentage = percentage;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("progressId", this.progressId);
+    b.add("message", this.message);
+    b.add("percentage", this.percentage);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ProgressUpdateEventArguments other = (ProgressUpdateEventArguments) obj;
+    if (this.progressId == null) {
+      if (other.progressId != null)
+        return false;
+    } else if (!this.progressId.equals(other.progressId))
+      return false;
+    if (this.message == null) {
+      if (other.message != null)
+        return false;
+    } else if (!this.message.equals(other.message))
+      return false;
+    if (this.percentage == null) {
+      if (other.percentage != null)
+        return false;
+    } else if (!this.percentage.equals(other.percentage))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.progressId== null) ? 0 : this.progressId.hashCode());
+    result = prime * result + ((this.message== null) ? 0 : this.message.hashCode());
+    return prime * result + ((this.percentage== null) ? 0 : this.percentage.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ReadMemoryArguments.java b/java/org/eclipse/lsp4j/debug/ReadMemoryArguments.java
new file mode 100644
index 0000000..56b5fe8
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ReadMemoryArguments.java
@@ -0,0 +1,136 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'readMemory' request.
+ */
+@SuppressWarnings("all")
+public class ReadMemoryArguments {
+  /**
+   * Memory reference to the base location from which data should be read.
+   */
+  @NonNull
+  private String memoryReference;
+  
+  /**
+   * Optional offset (in bytes) to be applied to the reference location before reading data. Can be negative.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer offset;
+  
+  /**
+   * Number of bytes to read at the specified location and offset.
+   */
+  private int count;
+  
+  /**
+   * Memory reference to the base location from which data should be read.
+   */
+  @Pure
+  @NonNull
+  public String getMemoryReference() {
+    return this.memoryReference;
+  }
+  
+  /**
+   * Memory reference to the base location from which data should be read.
+   */
+  public void setMemoryReference(@NonNull final String memoryReference) {
+    this.memoryReference = Preconditions.checkNotNull(memoryReference, "memoryReference");
+  }
+  
+  /**
+   * Optional offset (in bytes) to be applied to the reference location before reading data. Can be negative.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getOffset() {
+    return this.offset;
+  }
+  
+  /**
+   * Optional offset (in bytes) to be applied to the reference location before reading data. Can be negative.
+   * <p>
+   * This is an optional property.
+   */
+  public void setOffset(final Integer offset) {
+    this.offset = offset;
+  }
+  
+  /**
+   * Number of bytes to read at the specified location and offset.
+   */
+  @Pure
+  public int getCount() {
+    return this.count;
+  }
+  
+  /**
+   * Number of bytes to read at the specified location and offset.
+   */
+  public void setCount(final int count) {
+    this.count = count;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("memoryReference", this.memoryReference);
+    b.add("offset", this.offset);
+    b.add("count", this.count);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ReadMemoryArguments other = (ReadMemoryArguments) obj;
+    if (this.memoryReference == null) {
+      if (other.memoryReference != null)
+        return false;
+    } else if (!this.memoryReference.equals(other.memoryReference))
+      return false;
+    if (this.offset == null) {
+      if (other.offset != null)
+        return false;
+    } else if (!this.offset.equals(other.offset))
+      return false;
+    if (other.count != this.count)
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.memoryReference== null) ? 0 : this.memoryReference.hashCode());
+    result = prime * result + ((this.offset== null) ? 0 : this.offset.hashCode());
+    return prime * result + this.count;
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ReadMemoryResponse.java b/java/org/eclipse/lsp4j/debug/ReadMemoryResponse.java
new file mode 100644
index 0000000..6db549f
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ReadMemoryResponse.java
@@ -0,0 +1,160 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Response to 'readMemory' request.
+ */
+@SuppressWarnings("all")
+public class ReadMemoryResponse {
+  /**
+   * The address of the first byte of data returned.
+   * <p>
+   * Treated as a hex value if prefixed with '0x', or as a decimal value otherwise.
+   */
+  @NonNull
+  private String address;
+  
+  /**
+   * The number of unreadable bytes encountered after the last successfully read byte.
+   * <p>
+   * This can be used to determine the number of bytes that must be skipped before a subsequent 'readMemory' request
+   * will succeed.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer unreadableBytes;
+  
+  /**
+   * The bytes read from memory, encoded using base64.
+   * <p>
+   * This is an optional property.
+   */
+  private String data;
+  
+  /**
+   * The address of the first byte of data returned.
+   * <p>
+   * Treated as a hex value if prefixed with '0x', or as a decimal value otherwise.
+   */
+  @Pure
+  @NonNull
+  public String getAddress() {
+    return this.address;
+  }
+  
+  /**
+   * The address of the first byte of data returned.
+   * <p>
+   * Treated as a hex value if prefixed with '0x', or as a decimal value otherwise.
+   */
+  public void setAddress(@NonNull final String address) {
+    this.address = Preconditions.checkNotNull(address, "address");
+  }
+  
+  /**
+   * The number of unreadable bytes encountered after the last successfully read byte.
+   * <p>
+   * This can be used to determine the number of bytes that must be skipped before a subsequent 'readMemory' request
+   * will succeed.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getUnreadableBytes() {
+    return this.unreadableBytes;
+  }
+  
+  /**
+   * The number of unreadable bytes encountered after the last successfully read byte.
+   * <p>
+   * This can be used to determine the number of bytes that must be skipped before a subsequent 'readMemory' request
+   * will succeed.
+   * <p>
+   * This is an optional property.
+   */
+  public void setUnreadableBytes(final Integer unreadableBytes) {
+    this.unreadableBytes = unreadableBytes;
+  }
+  
+  /**
+   * The bytes read from memory, encoded using base64.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getData() {
+    return this.data;
+  }
+  
+  /**
+   * The bytes read from memory, encoded using base64.
+   * <p>
+   * This is an optional property.
+   */
+  public void setData(final String data) {
+    this.data = data;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("address", this.address);
+    b.add("unreadableBytes", this.unreadableBytes);
+    b.add("data", this.data);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ReadMemoryResponse other = (ReadMemoryResponse) obj;
+    if (this.address == null) {
+      if (other.address != null)
+        return false;
+    } else if (!this.address.equals(other.address))
+      return false;
+    if (this.unreadableBytes == null) {
+      if (other.unreadableBytes != null)
+        return false;
+    } else if (!this.unreadableBytes.equals(other.unreadableBytes))
+      return false;
+    if (this.data == null) {
+      if (other.data != null)
+        return false;
+    } else if (!this.data.equals(other.data))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.address== null) ? 0 : this.address.hashCode());
+    result = prime * result + ((this.unreadableBytes== null) ? 0 : this.unreadableBytes.hashCode());
+    return prime * result + ((this.data== null) ? 0 : this.data.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/RestartArguments.java b/java/org/eclipse/lsp4j/debug/RestartArguments.java
new file mode 100644
index 0000000..0a19d03
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/RestartArguments.java
@@ -0,0 +1,46 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'restart' request.
+ */
+@SuppressWarnings("all")
+public class RestartArguments {
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 1;
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/RestartFrameArguments.java b/java/org/eclipse/lsp4j/debug/RestartFrameArguments.java
new file mode 100644
index 0000000..1505820
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/RestartFrameArguments.java
@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'restartFrame' request.
+ */
+@SuppressWarnings("all")
+public class RestartFrameArguments {
+  /**
+   * Restart this stackframe.
+   */
+  private int frameId;
+  
+  /**
+   * Restart this stackframe.
+   */
+  @Pure
+  public int getFrameId() {
+    return this.frameId;
+  }
+  
+  /**
+   * Restart this stackframe.
+   */
+  public void setFrameId(final int frameId) {
+    this.frameId = frameId;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("frameId", this.frameId);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    RestartFrameArguments other = (RestartFrameArguments) obj;
+    if (other.frameId != this.frameId)
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + this.frameId;
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ReverseContinueArguments.java b/java/org/eclipse/lsp4j/debug/ReverseContinueArguments.java
new file mode 100644
index 0000000..d7ca1a2
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ReverseContinueArguments.java
@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'reverseContinue' request.
+ */
+@SuppressWarnings("all")
+public class ReverseContinueArguments {
+  /**
+   * Execute 'reverseContinue' for this thread.
+   */
+  private int threadId;
+  
+  /**
+   * Execute 'reverseContinue' for this thread.
+   */
+  @Pure
+  public int getThreadId() {
+    return this.threadId;
+  }
+  
+  /**
+   * Execute 'reverseContinue' for this thread.
+   */
+  public void setThreadId(final int threadId) {
+    this.threadId = threadId;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("threadId", this.threadId);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ReverseContinueArguments other = (ReverseContinueArguments) obj;
+    if (other.threadId != this.threadId)
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + this.threadId;
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/RunInTerminalRequestArguments.java b/java/org/eclipse/lsp4j/debug/RunInTerminalRequestArguments.java
new file mode 100644
index 0000000..f403010
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/RunInTerminalRequestArguments.java
@@ -0,0 +1,213 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import java.util.Map;
+import org.eclipse.lsp4j.debug.RunInTerminalRequestArgumentsKind;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'runInTerminal' request.
+ */
+@SuppressWarnings("all")
+public class RunInTerminalRequestArguments {
+  /**
+   * What kind of terminal to launch.
+   * <p>
+   * This is an optional property.
+   */
+  private RunInTerminalRequestArgumentsKind kind;
+  
+  /**
+   * Optional title of the terminal.
+   * <p>
+   * This is an optional property.
+   */
+  private String title;
+  
+  /**
+   * Working directory for the command. For non-empty, valid paths this typically results in execution of a change
+   * directory command.
+   */
+  @NonNull
+  private String cwd;
+  
+  /**
+   * List of arguments. The first argument is the command to run.
+   */
+  @NonNull
+  private String[] args;
+  
+  /**
+   * Environment key-value pairs that are added to or removed from the default environment.
+   * <p>
+   * This is an optional property.
+   */
+  private Map<String, String> env;
+  
+  /**
+   * What kind of terminal to launch.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public RunInTerminalRequestArgumentsKind getKind() {
+    return this.kind;
+  }
+  
+  /**
+   * What kind of terminal to launch.
+   * <p>
+   * This is an optional property.
+   */
+  public void setKind(final RunInTerminalRequestArgumentsKind kind) {
+    this.kind = kind;
+  }
+  
+  /**
+   * Optional title of the terminal.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getTitle() {
+    return this.title;
+  }
+  
+  /**
+   * Optional title of the terminal.
+   * <p>
+   * This is an optional property.
+   */
+  public void setTitle(final String title) {
+    this.title = title;
+  }
+  
+  /**
+   * Working directory for the command. For non-empty, valid paths this typically results in execution of a change
+   * directory command.
+   */
+  @Pure
+  @NonNull
+  public String getCwd() {
+    return this.cwd;
+  }
+  
+  /**
+   * Working directory for the command. For non-empty, valid paths this typically results in execution of a change
+   * directory command.
+   */
+  public void setCwd(@NonNull final String cwd) {
+    this.cwd = Preconditions.checkNotNull(cwd, "cwd");
+  }
+  
+  /**
+   * List of arguments. The first argument is the command to run.
+   */
+  @Pure
+  @NonNull
+  public String[] getArgs() {
+    return this.args;
+  }
+  
+  /**
+   * List of arguments. The first argument is the command to run.
+   */
+  public void setArgs(@NonNull final String[] args) {
+    this.args = Preconditions.checkNotNull(args, "args");
+  }
+  
+  /**
+   * Environment key-value pairs that are added to or removed from the default environment.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Map<String, String> getEnv() {
+    return this.env;
+  }
+  
+  /**
+   * Environment key-value pairs that are added to or removed from the default environment.
+   * <p>
+   * This is an optional property.
+   */
+  public void setEnv(final Map<String, String> env) {
+    this.env = env;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("kind", this.kind);
+    b.add("title", this.title);
+    b.add("cwd", this.cwd);
+    b.add("args", this.args);
+    b.add("env", this.env);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    RunInTerminalRequestArguments other = (RunInTerminalRequestArguments) obj;
+    if (this.kind == null) {
+      if (other.kind != null)
+        return false;
+    } else if (!this.kind.equals(other.kind))
+      return false;
+    if (this.title == null) {
+      if (other.title != null)
+        return false;
+    } else if (!this.title.equals(other.title))
+      return false;
+    if (this.cwd == null) {
+      if (other.cwd != null)
+        return false;
+    } else if (!this.cwd.equals(other.cwd))
+      return false;
+    if (this.args == null) {
+      if (other.args != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.args, other.args))
+      return false;
+    if (this.env == null) {
+      if (other.env != null)
+        return false;
+    } else if (!this.env.equals(other.env))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.kind== null) ? 0 : this.kind.hashCode());
+    result = prime * result + ((this.title== null) ? 0 : this.title.hashCode());
+    result = prime * result + ((this.cwd== null) ? 0 : this.cwd.hashCode());
+    result = prime * result + ((this.args== null) ? 0 : Arrays.deepHashCode(this.args));
+    return prime * result + ((this.env== null) ? 0 : this.env.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/RunInTerminalRequestArgumentsKind.java b/java/org/eclipse/lsp4j/debug/RunInTerminalRequestArgumentsKind.java
new file mode 100644
index 0000000..f579038
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/RunInTerminalRequestArgumentsKind.java
@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+/**
+ * What kind of terminal to launch.
+ */
+@SuppressWarnings("all")
+public enum RunInTerminalRequestArgumentsKind {
+  INTEGRATED,
+  
+  EXTERNAL;
+}
diff --git a/java/org/eclipse/lsp4j/debug/RunInTerminalResponse.java b/java/org/eclipse/lsp4j/debug/RunInTerminalResponse.java
new file mode 100644
index 0000000..8d84fc0
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/RunInTerminalResponse.java
@@ -0,0 +1,114 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Response to 'runInTerminal' request.
+ */
+@SuppressWarnings("all")
+public class RunInTerminalResponse {
+  /**
+   * The process ID. The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  private Integer processId;
+  
+  /**
+   * The process ID of the terminal shell. The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  private Integer shellProcessId;
+  
+  /**
+   * The process ID. The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getProcessId() {
+    return this.processId;
+  }
+  
+  /**
+   * The process ID. The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  public void setProcessId(final Integer processId) {
+    this.processId = processId;
+  }
+  
+  /**
+   * The process ID of the terminal shell. The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getShellProcessId() {
+    return this.shellProcessId;
+  }
+  
+  /**
+   * The process ID of the terminal shell. The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  public void setShellProcessId(final Integer shellProcessId) {
+    this.shellProcessId = shellProcessId;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("processId", this.processId);
+    b.add("shellProcessId", this.shellProcessId);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    RunInTerminalResponse other = (RunInTerminalResponse) obj;
+    if (this.processId == null) {
+      if (other.processId != null)
+        return false;
+    } else if (!this.processId.equals(other.processId))
+      return false;
+    if (this.shellProcessId == null) {
+      if (other.shellProcessId != null)
+        return false;
+    } else if (!this.shellProcessId.equals(other.shellProcessId))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.processId== null) ? 0 : this.processId.hashCode());
+    return prime * result + ((this.shellProcessId== null) ? 0 : this.shellProcessId.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/Scope.java b/java/org/eclipse/lsp4j/debug/Scope.java
new file mode 100644
index 0000000..c4fedc3
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/Scope.java
@@ -0,0 +1,419 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.Source;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A Scope is a named container for variables. Optionally a scope can map to a source or a range within a source.
+ */
+@SuppressWarnings("all")
+public class Scope {
+  /**
+   * Name of the scope such as 'Arguments', 'Locals', or 'Registers'. This string is shown in the UI as is and can
+   * be translated.
+   */
+  @NonNull
+  private String name;
+  
+  /**
+   * An optional hint for how to present this scope in the UI. If this attribute is missing, the scope is shown with
+   * a generic UI.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link ScopePresentationHint}
+   */
+  private String presentationHint;
+  
+  /**
+   * The variables of this scope can be retrieved by passing the value of variablesReference to the
+   * VariablesRequest.
+   */
+  private int variablesReference;
+  
+  /**
+   * The number of named variables in this scope.
+   * <p>
+   * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer namedVariables;
+  
+  /**
+   * The number of indexed variables in this scope.
+   * <p>
+   * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer indexedVariables;
+  
+  /**
+   * If true, the number of variables in this scope is large or expensive to retrieve.
+   */
+  private boolean expensive;
+  
+  /**
+   * Optional source for this scope.
+   * <p>
+   * This is an optional property.
+   */
+  private Source source;
+  
+  /**
+   * Optional start line of the range covered by this scope.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer line;
+  
+  /**
+   * Optional start column of the range covered by this scope.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer column;
+  
+  /**
+   * Optional end line of the range covered by this scope.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer endLine;
+  
+  /**
+   * Optional end column of the range covered by this scope.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer endColumn;
+  
+  /**
+   * Name of the scope such as 'Arguments', 'Locals', or 'Registers'. This string is shown in the UI as is and can
+   * be translated.
+   */
+  @Pure
+  @NonNull
+  public String getName() {
+    return this.name;
+  }
+  
+  /**
+   * Name of the scope such as 'Arguments', 'Locals', or 'Registers'. This string is shown in the UI as is and can
+   * be translated.
+   */
+  public void setName(@NonNull final String name) {
+    this.name = Preconditions.checkNotNull(name, "name");
+  }
+  
+  /**
+   * An optional hint for how to present this scope in the UI. If this attribute is missing, the scope is shown with
+   * a generic UI.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link ScopePresentationHint}
+   */
+  @Pure
+  public String getPresentationHint() {
+    return this.presentationHint;
+  }
+  
+  /**
+   * An optional hint for how to present this scope in the UI. If this attribute is missing, the scope is shown with
+   * a generic UI.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link ScopePresentationHint}
+   */
+  public void setPresentationHint(final String presentationHint) {
+    this.presentationHint = presentationHint;
+  }
+  
+  /**
+   * The variables of this scope can be retrieved by passing the value of variablesReference to the
+   * VariablesRequest.
+   */
+  @Pure
+  public int getVariablesReference() {
+    return this.variablesReference;
+  }
+  
+  /**
+   * The variables of this scope can be retrieved by passing the value of variablesReference to the
+   * VariablesRequest.
+   */
+  public void setVariablesReference(final int variablesReference) {
+    this.variablesReference = variablesReference;
+  }
+  
+  /**
+   * The number of named variables in this scope.
+   * <p>
+   * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getNamedVariables() {
+    return this.namedVariables;
+  }
+  
+  /**
+   * The number of named variables in this scope.
+   * <p>
+   * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+   * <p>
+   * This is an optional property.
+   */
+  public void setNamedVariables(final Integer namedVariables) {
+    this.namedVariables = namedVariables;
+  }
+  
+  /**
+   * The number of indexed variables in this scope.
+   * <p>
+   * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getIndexedVariables() {
+    return this.indexedVariables;
+  }
+  
+  /**
+   * The number of indexed variables in this scope.
+   * <p>
+   * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+   * <p>
+   * This is an optional property.
+   */
+  public void setIndexedVariables(final Integer indexedVariables) {
+    this.indexedVariables = indexedVariables;
+  }
+  
+  /**
+   * If true, the number of variables in this scope is large or expensive to retrieve.
+   */
+  @Pure
+  public boolean isExpensive() {
+    return this.expensive;
+  }
+  
+  /**
+   * If true, the number of variables in this scope is large or expensive to retrieve.
+   */
+  public void setExpensive(final boolean expensive) {
+    this.expensive = expensive;
+  }
+  
+  /**
+   * Optional source for this scope.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Source getSource() {
+    return this.source;
+  }
+  
+  /**
+   * Optional source for this scope.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSource(final Source source) {
+    this.source = source;
+  }
+  
+  /**
+   * Optional start line of the range covered by this scope.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getLine() {
+    return this.line;
+  }
+  
+  /**
+   * Optional start line of the range covered by this scope.
+   * <p>
+   * This is an optional property.
+   */
+  public void setLine(final Integer line) {
+    this.line = line;
+  }
+  
+  /**
+   * Optional start column of the range covered by this scope.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getColumn() {
+    return this.column;
+  }
+  
+  /**
+   * Optional start column of the range covered by this scope.
+   * <p>
+   * This is an optional property.
+   */
+  public void setColumn(final Integer column) {
+    this.column = column;
+  }
+  
+  /**
+   * Optional end line of the range covered by this scope.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getEndLine() {
+    return this.endLine;
+  }
+  
+  /**
+   * Optional end line of the range covered by this scope.
+   * <p>
+   * This is an optional property.
+   */
+  public void setEndLine(final Integer endLine) {
+    this.endLine = endLine;
+  }
+  
+  /**
+   * Optional end column of the range covered by this scope.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getEndColumn() {
+    return this.endColumn;
+  }
+  
+  /**
+   * Optional end column of the range covered by this scope.
+   * <p>
+   * This is an optional property.
+   */
+  public void setEndColumn(final Integer endColumn) {
+    this.endColumn = endColumn;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("name", this.name);
+    b.add("presentationHint", this.presentationHint);
+    b.add("variablesReference", this.variablesReference);
+    b.add("namedVariables", this.namedVariables);
+    b.add("indexedVariables", this.indexedVariables);
+    b.add("expensive", this.expensive);
+    b.add("source", this.source);
+    b.add("line", this.line);
+    b.add("column", this.column);
+    b.add("endLine", this.endLine);
+    b.add("endColumn", this.endColumn);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    Scope other = (Scope) obj;
+    if (this.name == null) {
+      if (other.name != null)
+        return false;
+    } else if (!this.name.equals(other.name))
+      return false;
+    if (this.presentationHint == null) {
+      if (other.presentationHint != null)
+        return false;
+    } else if (!this.presentationHint.equals(other.presentationHint))
+      return false;
+    if (other.variablesReference != this.variablesReference)
+      return false;
+    if (this.namedVariables == null) {
+      if (other.namedVariables != null)
+        return false;
+    } else if (!this.namedVariables.equals(other.namedVariables))
+      return false;
+    if (this.indexedVariables == null) {
+      if (other.indexedVariables != null)
+        return false;
+    } else if (!this.indexedVariables.equals(other.indexedVariables))
+      return false;
+    if (other.expensive != this.expensive)
+      return false;
+    if (this.source == null) {
+      if (other.source != null)
+        return false;
+    } else if (!this.source.equals(other.source))
+      return false;
+    if (this.line == null) {
+      if (other.line != null)
+        return false;
+    } else if (!this.line.equals(other.line))
+      return false;
+    if (this.column == null) {
+      if (other.column != null)
+        return false;
+    } else if (!this.column.equals(other.column))
+      return false;
+    if (this.endLine == null) {
+      if (other.endLine != null)
+        return false;
+    } else if (!this.endLine.equals(other.endLine))
+      return false;
+    if (this.endColumn == null) {
+      if (other.endColumn != null)
+        return false;
+    } else if (!this.endColumn.equals(other.endColumn))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.name== null) ? 0 : this.name.hashCode());
+    result = prime * result + ((this.presentationHint== null) ? 0 : this.presentationHint.hashCode());
+    result = prime * result + this.variablesReference;
+    result = prime * result + ((this.namedVariables== null) ? 0 : this.namedVariables.hashCode());
+    result = prime * result + ((this.indexedVariables== null) ? 0 : this.indexedVariables.hashCode());
+    result = prime * result + (this.expensive ? 1231 : 1237);
+    result = prime * result + ((this.source== null) ? 0 : this.source.hashCode());
+    result = prime * result + ((this.line== null) ? 0 : this.line.hashCode());
+    result = prime * result + ((this.column== null) ? 0 : this.column.hashCode());
+    result = prime * result + ((this.endLine== null) ? 0 : this.endLine.hashCode());
+    return prime * result + ((this.endColumn== null) ? 0 : this.endColumn.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ScopePresentationHint.java b/java/org/eclipse/lsp4j/debug/ScopePresentationHint.java
new file mode 100644
index 0000000..3412230
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ScopePresentationHint.java
@@ -0,0 +1,36 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+/**
+ * An optional hint for how to present this scope in the UI. If this attribute is missing, the scope is shown with
+ * a generic UI.
+ * <p>
+ * Possible values include - but not limited to those defined in {@link ScopePresentationHint}
+ */
+@SuppressWarnings("all")
+public interface ScopePresentationHint {
+  /**
+   * Scope contains method arguments.
+   */
+  static final String ARGUMENTS = "arguments";
+  
+  /**
+   * Scope contains local variables.
+   */
+  static final String LOCALS = "locals";
+  
+  /**
+   * Scope contains registers. Only a single 'registers' scope should be returned from a 'scopes' request.
+   */
+  static final String REGISTERS = "registers";
+}
diff --git a/java/org/eclipse/lsp4j/debug/ScopesArguments.java b/java/org/eclipse/lsp4j/debug/ScopesArguments.java
new file mode 100644
index 0000000..ccbf180
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ScopesArguments.java
@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'scopes' request.
+ */
+@SuppressWarnings("all")
+public class ScopesArguments {
+  /**
+   * Retrieve the scopes for this stackframe.
+   */
+  private int frameId;
+  
+  /**
+   * Retrieve the scopes for this stackframe.
+   */
+  @Pure
+  public int getFrameId() {
+    return this.frameId;
+  }
+  
+  /**
+   * Retrieve the scopes for this stackframe.
+   */
+  public void setFrameId(final int frameId) {
+    this.frameId = frameId;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("frameId", this.frameId);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ScopesArguments other = (ScopesArguments) obj;
+    if (other.frameId != this.frameId)
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + this.frameId;
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ScopesResponse.java b/java/org/eclipse/lsp4j/debug/ScopesResponse.java
new file mode 100644
index 0000000..136c530
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ScopesResponse.java
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.lsp4j.debug.Scope;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Response to 'scopes' request.
+ */
+@SuppressWarnings("all")
+public class ScopesResponse {
+  /**
+   * The scopes of the stackframe. If the array has length zero, there are no scopes available.
+   */
+  @NonNull
+  private Scope[] scopes;
+  
+  /**
+   * The scopes of the stackframe. If the array has length zero, there are no scopes available.
+   */
+  @Pure
+  @NonNull
+  public Scope[] getScopes() {
+    return this.scopes;
+  }
+  
+  /**
+   * The scopes of the stackframe. If the array has length zero, there are no scopes available.
+   */
+  public void setScopes(@NonNull final Scope[] scopes) {
+    this.scopes = Preconditions.checkNotNull(scopes, "scopes");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("scopes", this.scopes);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ScopesResponse other = (ScopesResponse) obj;
+    if (this.scopes == null) {
+      if (other.scopes != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.scopes, other.scopes))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.scopes== null) ? 0 : Arrays.deepHashCode(this.scopes));
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/SetBreakpointsArguments.java b/java/org/eclipse/lsp4j/debug/SetBreakpointsArguments.java
new file mode 100644
index 0000000..2235942
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/SetBreakpointsArguments.java
@@ -0,0 +1,193 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.lsp4j.debug.Source;
+import org.eclipse.lsp4j.debug.SourceBreakpoint;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'setBreakpoints' request.
+ */
+@SuppressWarnings("all")
+public class SetBreakpointsArguments {
+  /**
+   * The source location of the breakpoints; either 'source.path' or 'source.reference' must be specified.
+   */
+  @NonNull
+  private Source source;
+  
+  /**
+   * The code locations of the breakpoints.
+   * <p>
+   * This is an optional property.
+   */
+  private SourceBreakpoint[] breakpoints;
+  
+  /**
+   * Deprecated: The code locations of the breakpoints.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * @deprecated Use the line field in the breakpoints property instead.
+   */
+  @Deprecated
+  private int[] lines;
+  
+  /**
+   * A value of true indicates that the underlying source has been modified which results in new breakpoint
+   * locations.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean sourceModified;
+  
+  /**
+   * The source location of the breakpoints; either 'source.path' or 'source.reference' must be specified.
+   */
+  @Pure
+  @NonNull
+  public Source getSource() {
+    return this.source;
+  }
+  
+  /**
+   * The source location of the breakpoints; either 'source.path' or 'source.reference' must be specified.
+   */
+  public void setSource(@NonNull final Source source) {
+    this.source = Preconditions.checkNotNull(source, "source");
+  }
+  
+  /**
+   * The code locations of the breakpoints.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public SourceBreakpoint[] getBreakpoints() {
+    return this.breakpoints;
+  }
+  
+  /**
+   * The code locations of the breakpoints.
+   * <p>
+   * This is an optional property.
+   */
+  public void setBreakpoints(final SourceBreakpoint[] breakpoints) {
+    this.breakpoints = breakpoints;
+  }
+  
+  /**
+   * Deprecated: The code locations of the breakpoints.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * @deprecated Use the line field in the breakpoints property instead.
+   */
+  @Pure
+  @Deprecated
+  public int[] getLines() {
+    return this.lines;
+  }
+  
+  /**
+   * Deprecated: The code locations of the breakpoints.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * @deprecated Use the line field in the breakpoints property instead.
+   */
+  @Deprecated
+  public void setLines(final int[] lines) {
+    this.lines = lines;
+  }
+  
+  /**
+   * A value of true indicates that the underlying source has been modified which results in new breakpoint
+   * locations.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getSourceModified() {
+    return this.sourceModified;
+  }
+  
+  /**
+   * A value of true indicates that the underlying source has been modified which results in new breakpoint
+   * locations.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSourceModified(final Boolean sourceModified) {
+    this.sourceModified = sourceModified;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("source", this.source);
+    b.add("breakpoints", this.breakpoints);
+    b.add("lines", this.lines);
+    b.add("sourceModified", this.sourceModified);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SetBreakpointsArguments other = (SetBreakpointsArguments) obj;
+    if (this.source == null) {
+      if (other.source != null)
+        return false;
+    } else if (!this.source.equals(other.source))
+      return false;
+    if (this.breakpoints == null) {
+      if (other.breakpoints != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.breakpoints, other.breakpoints))
+      return false;
+    if (this.lines == null) {
+      if (other.lines != null)
+        return false;
+    } else if (!Arrays.equals(this.lines, other.lines))
+      return false;
+    if (this.sourceModified == null) {
+      if (other.sourceModified != null)
+        return false;
+    } else if (!this.sourceModified.equals(other.sourceModified))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.source== null) ? 0 : this.source.hashCode());
+    result = prime * result + ((this.breakpoints== null) ? 0 : Arrays.deepHashCode(this.breakpoints));
+    result = prime * result + ((this.lines== null) ? 0 : Arrays.hashCode(this.lines));
+    return prime * result + ((this.sourceModified== null) ? 0 : this.sourceModified.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/SetBreakpointsResponse.java b/java/org/eclipse/lsp4j/debug/SetBreakpointsResponse.java
new file mode 100644
index 0000000..4d64102
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/SetBreakpointsResponse.java
@@ -0,0 +1,96 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.lsp4j.debug.Breakpoint;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Response to 'setBreakpoints' request.
+ * <p>
+ * Returned is information about each breakpoint created by this request.
+ * <p>
+ * This includes the actual code location and whether the breakpoint could be verified.
+ * <p>
+ * The breakpoints returned are in the same order as the elements of the 'breakpoints'
+ * <p>
+ * (or the deprecated 'lines') array in the arguments.
+ */
+@SuppressWarnings("all")
+public class SetBreakpointsResponse {
+  /**
+   * Information about the breakpoints.
+   * <p>
+   * The array elements are in the same order as the elements of the 'breakpoints' (or the deprecated 'lines') array
+   * in the arguments.
+   */
+  @NonNull
+  private Breakpoint[] breakpoints;
+  
+  /**
+   * Information about the breakpoints.
+   * <p>
+   * The array elements are in the same order as the elements of the 'breakpoints' (or the deprecated 'lines') array
+   * in the arguments.
+   */
+  @Pure
+  @NonNull
+  public Breakpoint[] getBreakpoints() {
+    return this.breakpoints;
+  }
+  
+  /**
+   * Information about the breakpoints.
+   * <p>
+   * The array elements are in the same order as the elements of the 'breakpoints' (or the deprecated 'lines') array
+   * in the arguments.
+   */
+  public void setBreakpoints(@NonNull final Breakpoint[] breakpoints) {
+    this.breakpoints = Preconditions.checkNotNull(breakpoints, "breakpoints");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("breakpoints", this.breakpoints);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SetBreakpointsResponse other = (SetBreakpointsResponse) obj;
+    if (this.breakpoints == null) {
+      if (other.breakpoints != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.breakpoints, other.breakpoints))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.breakpoints== null) ? 0 : Arrays.deepHashCode(this.breakpoints));
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/SetDataBreakpointsArguments.java b/java/org/eclipse/lsp4j/debug/SetDataBreakpointsArguments.java
new file mode 100644
index 0000000..7b60d47
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/SetDataBreakpointsArguments.java
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.lsp4j.debug.DataBreakpoint;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'setDataBreakpoints' request.
+ */
+@SuppressWarnings("all")
+public class SetDataBreakpointsArguments {
+  /**
+   * The contents of this array replaces all existing data breakpoints. An empty array clears all data breakpoints.
+   */
+  @NonNull
+  private DataBreakpoint[] breakpoints;
+  
+  /**
+   * The contents of this array replaces all existing data breakpoints. An empty array clears all data breakpoints.
+   */
+  @Pure
+  @NonNull
+  public DataBreakpoint[] getBreakpoints() {
+    return this.breakpoints;
+  }
+  
+  /**
+   * The contents of this array replaces all existing data breakpoints. An empty array clears all data breakpoints.
+   */
+  public void setBreakpoints(@NonNull final DataBreakpoint[] breakpoints) {
+    this.breakpoints = Preconditions.checkNotNull(breakpoints, "breakpoints");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("breakpoints", this.breakpoints);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SetDataBreakpointsArguments other = (SetDataBreakpointsArguments) obj;
+    if (this.breakpoints == null) {
+      if (other.breakpoints != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.breakpoints, other.breakpoints))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.breakpoints== null) ? 0 : Arrays.deepHashCode(this.breakpoints));
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/SetDataBreakpointsResponse.java b/java/org/eclipse/lsp4j/debug/SetDataBreakpointsResponse.java
new file mode 100644
index 0000000..545a59c
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/SetDataBreakpointsResponse.java
@@ -0,0 +1,84 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.lsp4j.debug.Breakpoint;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Response to 'setDataBreakpoints' request.
+ * <p>
+ * Returned is information about each breakpoint created by this request.
+ */
+@SuppressWarnings("all")
+public class SetDataBreakpointsResponse {
+  /**
+   * Information about the data breakpoints. The array elements correspond to the elements of the input argument
+   * 'breakpoints' array.
+   */
+  @NonNull
+  private Breakpoint[] breakpoints;
+  
+  /**
+   * Information about the data breakpoints. The array elements correspond to the elements of the input argument
+   * 'breakpoints' array.
+   */
+  @Pure
+  @NonNull
+  public Breakpoint[] getBreakpoints() {
+    return this.breakpoints;
+  }
+  
+  /**
+   * Information about the data breakpoints. The array elements correspond to the elements of the input argument
+   * 'breakpoints' array.
+   */
+  public void setBreakpoints(@NonNull final Breakpoint[] breakpoints) {
+    this.breakpoints = Preconditions.checkNotNull(breakpoints, "breakpoints");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("breakpoints", this.breakpoints);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SetDataBreakpointsResponse other = (SetDataBreakpointsResponse) obj;
+    if (this.breakpoints == null) {
+      if (other.breakpoints != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.breakpoints, other.breakpoints))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.breakpoints== null) ? 0 : Arrays.deepHashCode(this.breakpoints));
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/SetExceptionBreakpointsArguments.java b/java/org/eclipse/lsp4j/debug/SetExceptionBreakpointsArguments.java
new file mode 100644
index 0000000..2ac9697
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/SetExceptionBreakpointsArguments.java
@@ -0,0 +1,163 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.lsp4j.debug.ExceptionFilterOptions;
+import org.eclipse.lsp4j.debug.ExceptionOptions;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'setExceptionBreakpoints' request.
+ */
+@SuppressWarnings("all")
+public class SetExceptionBreakpointsArguments {
+  /**
+   * Set of exception filters specified by their ID. The set of all possible exception filters is defined by the
+   * 'exceptionBreakpointFilters' capability. The 'filter' and 'filterOptions' sets are additive.
+   */
+  @NonNull
+  private String[] filters;
+  
+  /**
+   * Set of exception filters and their options. The set of all possible exception filters is defined by the
+   * 'exceptionBreakpointFilters' capability. This attribute is only honored by a debug adapter if the capability
+   * 'supportsExceptionFilterOptions' is true. The 'filter' and 'filterOptions' sets are additive.
+   * <p>
+   * This is an optional property.
+   */
+  private ExceptionFilterOptions[] filterOptions;
+  
+  /**
+   * Configuration options for selected exceptions.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportsExceptionOptions' is true.
+   * <p>
+   * This is an optional property.
+   */
+  private ExceptionOptions[] exceptionOptions;
+  
+  /**
+   * Set of exception filters specified by their ID. The set of all possible exception filters is defined by the
+   * 'exceptionBreakpointFilters' capability. The 'filter' and 'filterOptions' sets are additive.
+   */
+  @Pure
+  @NonNull
+  public String[] getFilters() {
+    return this.filters;
+  }
+  
+  /**
+   * Set of exception filters specified by their ID. The set of all possible exception filters is defined by the
+   * 'exceptionBreakpointFilters' capability. The 'filter' and 'filterOptions' sets are additive.
+   */
+  public void setFilters(@NonNull final String[] filters) {
+    this.filters = Preconditions.checkNotNull(filters, "filters");
+  }
+  
+  /**
+   * Set of exception filters and their options. The set of all possible exception filters is defined by the
+   * 'exceptionBreakpointFilters' capability. This attribute is only honored by a debug adapter if the capability
+   * 'supportsExceptionFilterOptions' is true. The 'filter' and 'filterOptions' sets are additive.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public ExceptionFilterOptions[] getFilterOptions() {
+    return this.filterOptions;
+  }
+  
+  /**
+   * Set of exception filters and their options. The set of all possible exception filters is defined by the
+   * 'exceptionBreakpointFilters' capability. This attribute is only honored by a debug adapter if the capability
+   * 'supportsExceptionFilterOptions' is true. The 'filter' and 'filterOptions' sets are additive.
+   * <p>
+   * This is an optional property.
+   */
+  public void setFilterOptions(final ExceptionFilterOptions[] filterOptions) {
+    this.filterOptions = filterOptions;
+  }
+  
+  /**
+   * Configuration options for selected exceptions.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportsExceptionOptions' is true.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public ExceptionOptions[] getExceptionOptions() {
+    return this.exceptionOptions;
+  }
+  
+  /**
+   * Configuration options for selected exceptions.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportsExceptionOptions' is true.
+   * <p>
+   * This is an optional property.
+   */
+  public void setExceptionOptions(final ExceptionOptions[] exceptionOptions) {
+    this.exceptionOptions = exceptionOptions;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("filters", this.filters);
+    b.add("filterOptions", this.filterOptions);
+    b.add("exceptionOptions", this.exceptionOptions);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SetExceptionBreakpointsArguments other = (SetExceptionBreakpointsArguments) obj;
+    if (this.filters == null) {
+      if (other.filters != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.filters, other.filters))
+      return false;
+    if (this.filterOptions == null) {
+      if (other.filterOptions != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.filterOptions, other.filterOptions))
+      return false;
+    if (this.exceptionOptions == null) {
+      if (other.exceptionOptions != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.exceptionOptions, other.exceptionOptions))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.filters== null) ? 0 : Arrays.deepHashCode(this.filters));
+    result = prime * result + ((this.filterOptions== null) ? 0 : Arrays.deepHashCode(this.filterOptions));
+    return prime * result + ((this.exceptionOptions== null) ? 0 : Arrays.deepHashCode(this.exceptionOptions));
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/SetExpressionArguments.java b/java/org/eclipse/lsp4j/debug/SetExpressionArguments.java
new file mode 100644
index 0000000..54097f9
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/SetExpressionArguments.java
@@ -0,0 +1,178 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.ValueFormat;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'setExpression' request.
+ */
+@SuppressWarnings("all")
+public class SetExpressionArguments {
+  /**
+   * The l-value expression to assign to.
+   */
+  @NonNull
+  private String expression;
+  
+  /**
+   * The value expression to assign to the l-value expression.
+   */
+  @NonNull
+  private String value;
+  
+  /**
+   * Evaluate the expressions in the scope of this stack frame. If not specified, the expressions are evaluated in
+   * the global scope.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer frameId;
+  
+  /**
+   * Specifies how the resulting value should be formatted.
+   * <p>
+   * This is an optional property.
+   */
+  private ValueFormat format;
+  
+  /**
+   * The l-value expression to assign to.
+   */
+  @Pure
+  @NonNull
+  public String getExpression() {
+    return this.expression;
+  }
+  
+  /**
+   * The l-value expression to assign to.
+   */
+  public void setExpression(@NonNull final String expression) {
+    this.expression = Preconditions.checkNotNull(expression, "expression");
+  }
+  
+  /**
+   * The value expression to assign to the l-value expression.
+   */
+  @Pure
+  @NonNull
+  public String getValue() {
+    return this.value;
+  }
+  
+  /**
+   * The value expression to assign to the l-value expression.
+   */
+  public void setValue(@NonNull final String value) {
+    this.value = Preconditions.checkNotNull(value, "value");
+  }
+  
+  /**
+   * Evaluate the expressions in the scope of this stack frame. If not specified, the expressions are evaluated in
+   * the global scope.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getFrameId() {
+    return this.frameId;
+  }
+  
+  /**
+   * Evaluate the expressions in the scope of this stack frame. If not specified, the expressions are evaluated in
+   * the global scope.
+   * <p>
+   * This is an optional property.
+   */
+  public void setFrameId(final Integer frameId) {
+    this.frameId = frameId;
+  }
+  
+  /**
+   * Specifies how the resulting value should be formatted.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public ValueFormat getFormat() {
+    return this.format;
+  }
+  
+  /**
+   * Specifies how the resulting value should be formatted.
+   * <p>
+   * This is an optional property.
+   */
+  public void setFormat(final ValueFormat format) {
+    this.format = format;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("expression", this.expression);
+    b.add("value", this.value);
+    b.add("frameId", this.frameId);
+    b.add("format", this.format);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SetExpressionArguments other = (SetExpressionArguments) obj;
+    if (this.expression == null) {
+      if (other.expression != null)
+        return false;
+    } else if (!this.expression.equals(other.expression))
+      return false;
+    if (this.value == null) {
+      if (other.value != null)
+        return false;
+    } else if (!this.value.equals(other.value))
+      return false;
+    if (this.frameId == null) {
+      if (other.frameId != null)
+        return false;
+    } else if (!this.frameId.equals(other.frameId))
+      return false;
+    if (this.format == null) {
+      if (other.format != null)
+        return false;
+    } else if (!this.format.equals(other.format))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.expression== null) ? 0 : this.expression.hashCode());
+    result = prime * result + ((this.value== null) ? 0 : this.value.hashCode());
+    result = prime * result + ((this.frameId== null) ? 0 : this.frameId.hashCode());
+    return prime * result + ((this.format== null) ? 0 : this.format.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/SetExpressionResponse.java b/java/org/eclipse/lsp4j/debug/SetExpressionResponse.java
new file mode 100644
index 0000000..2a1fb9c
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/SetExpressionResponse.java
@@ -0,0 +1,287 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.VariablePresentationHint;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Response to 'setExpression' request.
+ */
+@SuppressWarnings("all")
+public class SetExpressionResponse {
+  /**
+   * The new value of the expression.
+   */
+  @NonNull
+  private String value;
+  
+  /**
+   * The optional type of the value.
+   * <p>
+   * This attribute should only be returned by a debug adapter if the client has passed the value true for the
+   * 'supportsVariableType' capability of the 'initialize' request.
+   * <p>
+   * This is an optional property.
+   */
+  private String type;
+  
+  /**
+   * Properties of a value that can be used to determine how to render the result in the UI.
+   * <p>
+   * This is an optional property.
+   */
+  private VariablePresentationHint presentationHint;
+  
+  /**
+   * If variablesReference is &gt; 0, the value is structured and its children can be retrieved by passing
+   * variablesReference to the VariablesRequest.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  private Integer variablesReference;
+  
+  /**
+   * The number of named child variables.
+   * <p>
+   * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  private Integer namedVariables;
+  
+  /**
+   * The number of indexed child variables.
+   * <p>
+   * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  private Integer indexedVariables;
+  
+  /**
+   * The new value of the expression.
+   */
+  @Pure
+  @NonNull
+  public String getValue() {
+    return this.value;
+  }
+  
+  /**
+   * The new value of the expression.
+   */
+  public void setValue(@NonNull final String value) {
+    this.value = Preconditions.checkNotNull(value, "value");
+  }
+  
+  /**
+   * The optional type of the value.
+   * <p>
+   * This attribute should only be returned by a debug adapter if the client has passed the value true for the
+   * 'supportsVariableType' capability of the 'initialize' request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getType() {
+    return this.type;
+  }
+  
+  /**
+   * The optional type of the value.
+   * <p>
+   * This attribute should only be returned by a debug adapter if the client has passed the value true for the
+   * 'supportsVariableType' capability of the 'initialize' request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setType(final String type) {
+    this.type = type;
+  }
+  
+  /**
+   * Properties of a value that can be used to determine how to render the result in the UI.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public VariablePresentationHint getPresentationHint() {
+    return this.presentationHint;
+  }
+  
+  /**
+   * Properties of a value that can be used to determine how to render the result in the UI.
+   * <p>
+   * This is an optional property.
+   */
+  public void setPresentationHint(final VariablePresentationHint presentationHint) {
+    this.presentationHint = presentationHint;
+  }
+  
+  /**
+   * If variablesReference is &gt; 0, the value is structured and its children can be retrieved by passing
+   * variablesReference to the VariablesRequest.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getVariablesReference() {
+    return this.variablesReference;
+  }
+  
+  /**
+   * If variablesReference is &gt; 0, the value is structured and its children can be retrieved by passing
+   * variablesReference to the VariablesRequest.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  public void setVariablesReference(final Integer variablesReference) {
+    this.variablesReference = variablesReference;
+  }
+  
+  /**
+   * The number of named child variables.
+   * <p>
+   * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getNamedVariables() {
+    return this.namedVariables;
+  }
+  
+  /**
+   * The number of named child variables.
+   * <p>
+   * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  public void setNamedVariables(final Integer namedVariables) {
+    this.namedVariables = namedVariables;
+  }
+  
+  /**
+   * The number of indexed child variables.
+   * <p>
+   * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getIndexedVariables() {
+    return this.indexedVariables;
+  }
+  
+  /**
+   * The number of indexed child variables.
+   * <p>
+   * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  public void setIndexedVariables(final Integer indexedVariables) {
+    this.indexedVariables = indexedVariables;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("value", this.value);
+    b.add("type", this.type);
+    b.add("presentationHint", this.presentationHint);
+    b.add("variablesReference", this.variablesReference);
+    b.add("namedVariables", this.namedVariables);
+    b.add("indexedVariables", this.indexedVariables);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SetExpressionResponse other = (SetExpressionResponse) obj;
+    if (this.value == null) {
+      if (other.value != null)
+        return false;
+    } else if (!this.value.equals(other.value))
+      return false;
+    if (this.type == null) {
+      if (other.type != null)
+        return false;
+    } else if (!this.type.equals(other.type))
+      return false;
+    if (this.presentationHint == null) {
+      if (other.presentationHint != null)
+        return false;
+    } else if (!this.presentationHint.equals(other.presentationHint))
+      return false;
+    if (this.variablesReference == null) {
+      if (other.variablesReference != null)
+        return false;
+    } else if (!this.variablesReference.equals(other.variablesReference))
+      return false;
+    if (this.namedVariables == null) {
+      if (other.namedVariables != null)
+        return false;
+    } else if (!this.namedVariables.equals(other.namedVariables))
+      return false;
+    if (this.indexedVariables == null) {
+      if (other.indexedVariables != null)
+        return false;
+    } else if (!this.indexedVariables.equals(other.indexedVariables))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.value== null) ? 0 : this.value.hashCode());
+    result = prime * result + ((this.type== null) ? 0 : this.type.hashCode());
+    result = prime * result + ((this.presentationHint== null) ? 0 : this.presentationHint.hashCode());
+    result = prime * result + ((this.variablesReference== null) ? 0 : this.variablesReference.hashCode());
+    result = prime * result + ((this.namedVariables== null) ? 0 : this.namedVariables.hashCode());
+    return prime * result + ((this.indexedVariables== null) ? 0 : this.indexedVariables.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/SetFunctionBreakpointsArguments.java b/java/org/eclipse/lsp4j/debug/SetFunctionBreakpointsArguments.java
new file mode 100644
index 0000000..f4c70fb
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/SetFunctionBreakpointsArguments.java
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.lsp4j.debug.FunctionBreakpoint;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'setFunctionBreakpoints' request.
+ */
+@SuppressWarnings("all")
+public class SetFunctionBreakpointsArguments {
+  /**
+   * The function names of the breakpoints.
+   */
+  @NonNull
+  private FunctionBreakpoint[] breakpoints;
+  
+  /**
+   * The function names of the breakpoints.
+   */
+  @Pure
+  @NonNull
+  public FunctionBreakpoint[] getBreakpoints() {
+    return this.breakpoints;
+  }
+  
+  /**
+   * The function names of the breakpoints.
+   */
+  public void setBreakpoints(@NonNull final FunctionBreakpoint[] breakpoints) {
+    this.breakpoints = Preconditions.checkNotNull(breakpoints, "breakpoints");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("breakpoints", this.breakpoints);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SetFunctionBreakpointsArguments other = (SetFunctionBreakpointsArguments) obj;
+    if (this.breakpoints == null) {
+      if (other.breakpoints != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.breakpoints, other.breakpoints))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.breakpoints== null) ? 0 : Arrays.deepHashCode(this.breakpoints));
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/SetFunctionBreakpointsResponse.java b/java/org/eclipse/lsp4j/debug/SetFunctionBreakpointsResponse.java
new file mode 100644
index 0000000..94991b0
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/SetFunctionBreakpointsResponse.java
@@ -0,0 +1,81 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.lsp4j.debug.Breakpoint;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Response to 'setFunctionBreakpoints' request.
+ * <p>
+ * Returned is information about each breakpoint created by this request.
+ */
+@SuppressWarnings("all")
+public class SetFunctionBreakpointsResponse {
+  /**
+   * Information about the breakpoints. The array elements correspond to the elements of the 'breakpoints' array.
+   */
+  @NonNull
+  private Breakpoint[] breakpoints;
+  
+  /**
+   * Information about the breakpoints. The array elements correspond to the elements of the 'breakpoints' array.
+   */
+  @Pure
+  @NonNull
+  public Breakpoint[] getBreakpoints() {
+    return this.breakpoints;
+  }
+  
+  /**
+   * Information about the breakpoints. The array elements correspond to the elements of the 'breakpoints' array.
+   */
+  public void setBreakpoints(@NonNull final Breakpoint[] breakpoints) {
+    this.breakpoints = Preconditions.checkNotNull(breakpoints, "breakpoints");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("breakpoints", this.breakpoints);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SetFunctionBreakpointsResponse other = (SetFunctionBreakpointsResponse) obj;
+    if (this.breakpoints == null) {
+      if (other.breakpoints != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.breakpoints, other.breakpoints))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.breakpoints== null) ? 0 : Arrays.deepHashCode(this.breakpoints));
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/SetInstructionBreakpointsArguments.java b/java/org/eclipse/lsp4j/debug/SetInstructionBreakpointsArguments.java
new file mode 100644
index 0000000..e887bd5
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/SetInstructionBreakpointsArguments.java
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.lsp4j.debug.InstructionBreakpoint;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'setInstructionBreakpoints' request
+ */
+@SuppressWarnings("all")
+public class SetInstructionBreakpointsArguments {
+  /**
+   * The instruction references of the breakpoints
+   */
+  @NonNull
+  private InstructionBreakpoint[] breakpoints;
+  
+  /**
+   * The instruction references of the breakpoints
+   */
+  @Pure
+  @NonNull
+  public InstructionBreakpoint[] getBreakpoints() {
+    return this.breakpoints;
+  }
+  
+  /**
+   * The instruction references of the breakpoints
+   */
+  public void setBreakpoints(@NonNull final InstructionBreakpoint[] breakpoints) {
+    this.breakpoints = Preconditions.checkNotNull(breakpoints, "breakpoints");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("breakpoints", this.breakpoints);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SetInstructionBreakpointsArguments other = (SetInstructionBreakpointsArguments) obj;
+    if (this.breakpoints == null) {
+      if (other.breakpoints != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.breakpoints, other.breakpoints))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.breakpoints== null) ? 0 : Arrays.deepHashCode(this.breakpoints));
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/SetInstructionBreakpointsResponse.java b/java/org/eclipse/lsp4j/debug/SetInstructionBreakpointsResponse.java
new file mode 100644
index 0000000..238b839
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/SetInstructionBreakpointsResponse.java
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.lsp4j.debug.Breakpoint;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Response to 'setInstructionBreakpoints' request
+ */
+@SuppressWarnings("all")
+public class SetInstructionBreakpointsResponse {
+  /**
+   * Information about the breakpoints. The array elements correspond to the elements of the 'breakpoints' array.
+   */
+  @NonNull
+  private Breakpoint[] breakpoints;
+  
+  /**
+   * Information about the breakpoints. The array elements correspond to the elements of the 'breakpoints' array.
+   */
+  @Pure
+  @NonNull
+  public Breakpoint[] getBreakpoints() {
+    return this.breakpoints;
+  }
+  
+  /**
+   * Information about the breakpoints. The array elements correspond to the elements of the 'breakpoints' array.
+   */
+  public void setBreakpoints(@NonNull final Breakpoint[] breakpoints) {
+    this.breakpoints = Preconditions.checkNotNull(breakpoints, "breakpoints");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("breakpoints", this.breakpoints);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SetInstructionBreakpointsResponse other = (SetInstructionBreakpointsResponse) obj;
+    if (this.breakpoints == null) {
+      if (other.breakpoints != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.breakpoints, other.breakpoints))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.breakpoints== null) ? 0 : Arrays.deepHashCode(this.breakpoints));
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/SetVariableArguments.java b/java/org/eclipse/lsp4j/debug/SetVariableArguments.java
new file mode 100644
index 0000000..689e812
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/SetVariableArguments.java
@@ -0,0 +1,166 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.ValueFormat;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'setVariable' request.
+ */
+@SuppressWarnings("all")
+public class SetVariableArguments {
+  /**
+   * The reference of the variable container.
+   */
+  private int variablesReference;
+  
+  /**
+   * The name of the variable in the container.
+   */
+  @NonNull
+  private String name;
+  
+  /**
+   * The value of the variable.
+   */
+  @NonNull
+  private String value;
+  
+  /**
+   * Specifies details on how to format the response value.
+   * <p>
+   * This is an optional property.
+   */
+  private ValueFormat format;
+  
+  /**
+   * The reference of the variable container.
+   */
+  @Pure
+  public int getVariablesReference() {
+    return this.variablesReference;
+  }
+  
+  /**
+   * The reference of the variable container.
+   */
+  public void setVariablesReference(final int variablesReference) {
+    this.variablesReference = variablesReference;
+  }
+  
+  /**
+   * The name of the variable in the container.
+   */
+  @Pure
+  @NonNull
+  public String getName() {
+    return this.name;
+  }
+  
+  /**
+   * The name of the variable in the container.
+   */
+  public void setName(@NonNull final String name) {
+    this.name = Preconditions.checkNotNull(name, "name");
+  }
+  
+  /**
+   * The value of the variable.
+   */
+  @Pure
+  @NonNull
+  public String getValue() {
+    return this.value;
+  }
+  
+  /**
+   * The value of the variable.
+   */
+  public void setValue(@NonNull final String value) {
+    this.value = Preconditions.checkNotNull(value, "value");
+  }
+  
+  /**
+   * Specifies details on how to format the response value.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public ValueFormat getFormat() {
+    return this.format;
+  }
+  
+  /**
+   * Specifies details on how to format the response value.
+   * <p>
+   * This is an optional property.
+   */
+  public void setFormat(final ValueFormat format) {
+    this.format = format;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("variablesReference", this.variablesReference);
+    b.add("name", this.name);
+    b.add("value", this.value);
+    b.add("format", this.format);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SetVariableArguments other = (SetVariableArguments) obj;
+    if (other.variablesReference != this.variablesReference)
+      return false;
+    if (this.name == null) {
+      if (other.name != null)
+        return false;
+    } else if (!this.name.equals(other.name))
+      return false;
+    if (this.value == null) {
+      if (other.value != null)
+        return false;
+    } else if (!this.value.equals(other.value))
+      return false;
+    if (this.format == null) {
+      if (other.format != null)
+        return false;
+    } else if (!this.format.equals(other.format))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + this.variablesReference;
+    result = prime * result + ((this.name== null) ? 0 : this.name.hashCode());
+    result = prime * result + ((this.value== null) ? 0 : this.value.hashCode());
+    return prime * result + ((this.format== null) ? 0 : this.format.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/SetVariableResponse.java b/java/org/eclipse/lsp4j/debug/SetVariableResponse.java
new file mode 100644
index 0000000..d633619
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/SetVariableResponse.java
@@ -0,0 +1,244 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Response to 'setVariable' request.
+ */
+@SuppressWarnings("all")
+public class SetVariableResponse {
+  /**
+   * The new value of the variable.
+   */
+  @NonNull
+  private String value;
+  
+  /**
+   * The type of the new value. Typically shown in the UI when hovering over the value.
+   * <p>
+   * This is an optional property.
+   */
+  private String type;
+  
+  /**
+   * If variablesReference is &gt; 0, the new value is structured and its children can be retrieved by passing
+   * variablesReference to the VariablesRequest.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  private Integer variablesReference;
+  
+  /**
+   * The number of named child variables.
+   * <p>
+   * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  private Integer namedVariables;
+  
+  /**
+   * The number of indexed child variables.
+   * <p>
+   * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  private Integer indexedVariables;
+  
+  /**
+   * The new value of the variable.
+   */
+  @Pure
+  @NonNull
+  public String getValue() {
+    return this.value;
+  }
+  
+  /**
+   * The new value of the variable.
+   */
+  public void setValue(@NonNull final String value) {
+    this.value = Preconditions.checkNotNull(value, "value");
+  }
+  
+  /**
+   * The type of the new value. Typically shown in the UI when hovering over the value.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getType() {
+    return this.type;
+  }
+  
+  /**
+   * The type of the new value. Typically shown in the UI when hovering over the value.
+   * <p>
+   * This is an optional property.
+   */
+  public void setType(final String type) {
+    this.type = type;
+  }
+  
+  /**
+   * If variablesReference is &gt; 0, the new value is structured and its children can be retrieved by passing
+   * variablesReference to the VariablesRequest.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getVariablesReference() {
+    return this.variablesReference;
+  }
+  
+  /**
+   * If variablesReference is &gt; 0, the new value is structured and its children can be retrieved by passing
+   * variablesReference to the VariablesRequest.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  public void setVariablesReference(final Integer variablesReference) {
+    this.variablesReference = variablesReference;
+  }
+  
+  /**
+   * The number of named child variables.
+   * <p>
+   * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getNamedVariables() {
+    return this.namedVariables;
+  }
+  
+  /**
+   * The number of named child variables.
+   * <p>
+   * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  public void setNamedVariables(final Integer namedVariables) {
+    this.namedVariables = namedVariables;
+  }
+  
+  /**
+   * The number of indexed child variables.
+   * <p>
+   * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getIndexedVariables() {
+    return this.indexedVariables;
+  }
+  
+  /**
+   * The number of indexed child variables.
+   * <p>
+   * The client can use this optional information to present the variables in a paged UI and fetch them in chunks.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  public void setIndexedVariables(final Integer indexedVariables) {
+    this.indexedVariables = indexedVariables;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("value", this.value);
+    b.add("type", this.type);
+    b.add("variablesReference", this.variablesReference);
+    b.add("namedVariables", this.namedVariables);
+    b.add("indexedVariables", this.indexedVariables);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SetVariableResponse other = (SetVariableResponse) obj;
+    if (this.value == null) {
+      if (other.value != null)
+        return false;
+    } else if (!this.value.equals(other.value))
+      return false;
+    if (this.type == null) {
+      if (other.type != null)
+        return false;
+    } else if (!this.type.equals(other.type))
+      return false;
+    if (this.variablesReference == null) {
+      if (other.variablesReference != null)
+        return false;
+    } else if (!this.variablesReference.equals(other.variablesReference))
+      return false;
+    if (this.namedVariables == null) {
+      if (other.namedVariables != null)
+        return false;
+    } else if (!this.namedVariables.equals(other.namedVariables))
+      return false;
+    if (this.indexedVariables == null) {
+      if (other.indexedVariables != null)
+        return false;
+    } else if (!this.indexedVariables.equals(other.indexedVariables))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.value== null) ? 0 : this.value.hashCode());
+    result = prime * result + ((this.type== null) ? 0 : this.type.hashCode());
+    result = prime * result + ((this.variablesReference== null) ? 0 : this.variablesReference.hashCode());
+    result = prime * result + ((this.namedVariables== null) ? 0 : this.namedVariables.hashCode());
+    return prime * result + ((this.indexedVariables== null) ? 0 : this.indexedVariables.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/Source.java b/java/org/eclipse/lsp4j/debug/Source.java
new file mode 100644
index 0000000..6d9e1ac
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/Source.java
@@ -0,0 +1,372 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.lsp4j.debug.Checksum;
+import org.eclipse.lsp4j.debug.SourcePresentationHint;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A Source is a descriptor for source code.
+ * <p>
+ * It is returned from the debug adapter as part of a StackFrame and it is used by clients when specifying
+ * breakpoints.
+ */
+@SuppressWarnings("all")
+public class Source {
+  /**
+   * The short name of the source. Every source returned from the debug adapter has a name.
+   * <p>
+   * When sending a source to the debug adapter this name is optional.
+   * <p>
+   * This is an optional property.
+   */
+  private String name;
+  
+  /**
+   * The path of the source to be shown in the UI.
+   * <p>
+   * It is only used to locate and load the content of the source if no sourceReference is specified (or its value
+   * is 0).
+   * <p>
+   * This is an optional property.
+   */
+  private String path;
+  
+  /**
+   * If sourceReference &gt; 0 the contents of the source must be retrieved through the SourceRequest (even if a
+   * path is specified).
+   * <p>
+   * A sourceReference is only valid for a session, so it must not be used to persist a source.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  private Integer sourceReference;
+  
+  /**
+   * An optional hint for how to present the source in the UI.
+   * <p>
+   * A value of 'deemphasize' can be used to indicate that the source is not available or that it is skipped on
+   * stepping.
+   * <p>
+   * This is an optional property.
+   */
+  private SourcePresentationHint presentationHint;
+  
+  /**
+   * The (optional) origin of this source: possible values 'internal module', 'inlined content from source map',
+   * etc.
+   * <p>
+   * This is an optional property.
+   */
+  private String origin;
+  
+  /**
+   * An optional list of sources that are related to this source. These may be the source that generated this
+   * source.
+   * <p>
+   * This is an optional property.
+   */
+  private Source[] sources;
+  
+  /**
+   * Optional data that a debug adapter might want to loop through the client.
+   * <p>
+   * The client should leave the data intact and persist it across sessions. The client should not interpret the
+   * data.
+   * <p>
+   * This is an optional property.
+   */
+  private Object adapterData;
+  
+  /**
+   * The checksums associated with this file.
+   * <p>
+   * This is an optional property.
+   */
+  private Checksum[] checksums;
+  
+  /**
+   * The short name of the source. Every source returned from the debug adapter has a name.
+   * <p>
+   * When sending a source to the debug adapter this name is optional.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getName() {
+    return this.name;
+  }
+  
+  /**
+   * The short name of the source. Every source returned from the debug adapter has a name.
+   * <p>
+   * When sending a source to the debug adapter this name is optional.
+   * <p>
+   * This is an optional property.
+   */
+  public void setName(final String name) {
+    this.name = name;
+  }
+  
+  /**
+   * The path of the source to be shown in the UI.
+   * <p>
+   * It is only used to locate and load the content of the source if no sourceReference is specified (or its value
+   * is 0).
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getPath() {
+    return this.path;
+  }
+  
+  /**
+   * The path of the source to be shown in the UI.
+   * <p>
+   * It is only used to locate and load the content of the source if no sourceReference is specified (or its value
+   * is 0).
+   * <p>
+   * This is an optional property.
+   */
+  public void setPath(final String path) {
+    this.path = path;
+  }
+  
+  /**
+   * If sourceReference &gt; 0 the contents of the source must be retrieved through the SourceRequest (even if a
+   * path is specified).
+   * <p>
+   * A sourceReference is only valid for a session, so it must not be used to persist a source.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getSourceReference() {
+    return this.sourceReference;
+  }
+  
+  /**
+   * If sourceReference &gt; 0 the contents of the source must be retrieved through the SourceRequest (even if a
+   * path is specified).
+   * <p>
+   * A sourceReference is only valid for a session, so it must not be used to persist a source.
+   * <p>
+   * The value should be less than or equal to 2147483647 (2^31-1).
+   * <p>
+   * This is an optional property.
+   */
+  public void setSourceReference(final Integer sourceReference) {
+    this.sourceReference = sourceReference;
+  }
+  
+  /**
+   * An optional hint for how to present the source in the UI.
+   * <p>
+   * A value of 'deemphasize' can be used to indicate that the source is not available or that it is skipped on
+   * stepping.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public SourcePresentationHint getPresentationHint() {
+    return this.presentationHint;
+  }
+  
+  /**
+   * An optional hint for how to present the source in the UI.
+   * <p>
+   * A value of 'deemphasize' can be used to indicate that the source is not available or that it is skipped on
+   * stepping.
+   * <p>
+   * This is an optional property.
+   */
+  public void setPresentationHint(final SourcePresentationHint presentationHint) {
+    this.presentationHint = presentationHint;
+  }
+  
+  /**
+   * The (optional) origin of this source: possible values 'internal module', 'inlined content from source map',
+   * etc.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getOrigin() {
+    return this.origin;
+  }
+  
+  /**
+   * The (optional) origin of this source: possible values 'internal module', 'inlined content from source map',
+   * etc.
+   * <p>
+   * This is an optional property.
+   */
+  public void setOrigin(final String origin) {
+    this.origin = origin;
+  }
+  
+  /**
+   * An optional list of sources that are related to this source. These may be the source that generated this
+   * source.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Source[] getSources() {
+    return this.sources;
+  }
+  
+  /**
+   * An optional list of sources that are related to this source. These may be the source that generated this
+   * source.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSources(final Source[] sources) {
+    this.sources = sources;
+  }
+  
+  /**
+   * Optional data that a debug adapter might want to loop through the client.
+   * <p>
+   * The client should leave the data intact and persist it across sessions. The client should not interpret the
+   * data.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Object getAdapterData() {
+    return this.adapterData;
+  }
+  
+  /**
+   * Optional data that a debug adapter might want to loop through the client.
+   * <p>
+   * The client should leave the data intact and persist it across sessions. The client should not interpret the
+   * data.
+   * <p>
+   * This is an optional property.
+   */
+  public void setAdapterData(final Object adapterData) {
+    this.adapterData = adapterData;
+  }
+  
+  /**
+   * The checksums associated with this file.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Checksum[] getChecksums() {
+    return this.checksums;
+  }
+  
+  /**
+   * The checksums associated with this file.
+   * <p>
+   * This is an optional property.
+   */
+  public void setChecksums(final Checksum[] checksums) {
+    this.checksums = checksums;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("name", this.name);
+    b.add("path", this.path);
+    b.add("sourceReference", this.sourceReference);
+    b.add("presentationHint", this.presentationHint);
+    b.add("origin", this.origin);
+    b.add("sources", this.sources);
+    b.add("adapterData", this.adapterData);
+    b.add("checksums", this.checksums);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    Source other = (Source) obj;
+    if (this.name == null) {
+      if (other.name != null)
+        return false;
+    } else if (!this.name.equals(other.name))
+      return false;
+    if (this.path == null) {
+      if (other.path != null)
+        return false;
+    } else if (!this.path.equals(other.path))
+      return false;
+    if (this.sourceReference == null) {
+      if (other.sourceReference != null)
+        return false;
+    } else if (!this.sourceReference.equals(other.sourceReference))
+      return false;
+    if (this.presentationHint == null) {
+      if (other.presentationHint != null)
+        return false;
+    } else if (!this.presentationHint.equals(other.presentationHint))
+      return false;
+    if (this.origin == null) {
+      if (other.origin != null)
+        return false;
+    } else if (!this.origin.equals(other.origin))
+      return false;
+    if (this.sources == null) {
+      if (other.sources != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.sources, other.sources))
+      return false;
+    if (this.adapterData == null) {
+      if (other.adapterData != null)
+        return false;
+    } else if (!this.adapterData.equals(other.adapterData))
+      return false;
+    if (this.checksums == null) {
+      if (other.checksums != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.checksums, other.checksums))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.name== null) ? 0 : this.name.hashCode());
+    result = prime * result + ((this.path== null) ? 0 : this.path.hashCode());
+    result = prime * result + ((this.sourceReference== null) ? 0 : this.sourceReference.hashCode());
+    result = prime * result + ((this.presentationHint== null) ? 0 : this.presentationHint.hashCode());
+    result = prime * result + ((this.origin== null) ? 0 : this.origin.hashCode());
+    result = prime * result + ((this.sources== null) ? 0 : Arrays.deepHashCode(this.sources));
+    result = prime * result + ((this.adapterData== null) ? 0 : this.adapterData.hashCode());
+    return prime * result + ((this.checksums== null) ? 0 : Arrays.deepHashCode(this.checksums));
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/SourceArguments.java b/java/org/eclipse/lsp4j/debug/SourceArguments.java
new file mode 100644
index 0000000..d335244
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/SourceArguments.java
@@ -0,0 +1,112 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.Source;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'source' request.
+ */
+@SuppressWarnings("all")
+public class SourceArguments {
+  /**
+   * Specifies the source content to load. Either source.path or source.sourceReference must be specified.
+   * <p>
+   * This is an optional property.
+   */
+  private Source source;
+  
+  /**
+   * The reference to the source. This is the same as source.sourceReference.
+   * <p>
+   * This is provided for backward compatibility since old backends do not understand the 'source' attribute.
+   */
+  private int sourceReference;
+  
+  /**
+   * Specifies the source content to load. Either source.path or source.sourceReference must be specified.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Source getSource() {
+    return this.source;
+  }
+  
+  /**
+   * Specifies the source content to load. Either source.path or source.sourceReference must be specified.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSource(final Source source) {
+    this.source = source;
+  }
+  
+  /**
+   * The reference to the source. This is the same as source.sourceReference.
+   * <p>
+   * This is provided for backward compatibility since old backends do not understand the 'source' attribute.
+   */
+  @Pure
+  public int getSourceReference() {
+    return this.sourceReference;
+  }
+  
+  /**
+   * The reference to the source. This is the same as source.sourceReference.
+   * <p>
+   * This is provided for backward compatibility since old backends do not understand the 'source' attribute.
+   */
+  public void setSourceReference(final int sourceReference) {
+    this.sourceReference = sourceReference;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("source", this.source);
+    b.add("sourceReference", this.sourceReference);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SourceArguments other = (SourceArguments) obj;
+    if (this.source == null) {
+      if (other.source != null)
+        return false;
+    } else if (!this.source.equals(other.source))
+      return false;
+    if (other.sourceReference != this.sourceReference)
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.source== null) ? 0 : this.source.hashCode());
+    return prime * result + this.sourceReference;
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/SourceBreakpoint.java b/java/org/eclipse/lsp4j/debug/SourceBreakpoint.java
new file mode 100644
index 0000000..d7562ee
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/SourceBreakpoint.java
@@ -0,0 +1,234 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Properties of a breakpoint or logpoint passed to the setBreakpoints request.
+ */
+@SuppressWarnings("all")
+public class SourceBreakpoint {
+  /**
+   * The source line of the breakpoint or logpoint.
+   */
+  private int line;
+  
+  /**
+   * An optional source column of the breakpoint.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer column;
+  
+  /**
+   * An optional expression for conditional breakpoints.
+   * <p>
+   * It is only honored by a debug adapter if the capability 'supportsConditionalBreakpoints' is true.
+   * <p>
+   * This is an optional property.
+   */
+  private String condition;
+  
+  /**
+   * An optional expression that controls how many hits of the breakpoint are ignored.
+   * <p>
+   * The backend is expected to interpret the expression as needed.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportsHitConditionalBreakpoints' is true.
+   * <p>
+   * This is an optional property.
+   */
+  private String hitCondition;
+  
+  /**
+   * If this attribute exists and is non-empty, the backend must not 'break' (stop)
+   * <p>
+   * but log the message instead. Expressions within {} are interpolated.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportsLogPoints' is true.
+   * <p>
+   * This is an optional property.
+   */
+  private String logMessage;
+  
+  /**
+   * The source line of the breakpoint or logpoint.
+   */
+  @Pure
+  public int getLine() {
+    return this.line;
+  }
+  
+  /**
+   * The source line of the breakpoint or logpoint.
+   */
+  public void setLine(final int line) {
+    this.line = line;
+  }
+  
+  /**
+   * An optional source column of the breakpoint.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getColumn() {
+    return this.column;
+  }
+  
+  /**
+   * An optional source column of the breakpoint.
+   * <p>
+   * This is an optional property.
+   */
+  public void setColumn(final Integer column) {
+    this.column = column;
+  }
+  
+  /**
+   * An optional expression for conditional breakpoints.
+   * <p>
+   * It is only honored by a debug adapter if the capability 'supportsConditionalBreakpoints' is true.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getCondition() {
+    return this.condition;
+  }
+  
+  /**
+   * An optional expression for conditional breakpoints.
+   * <p>
+   * It is only honored by a debug adapter if the capability 'supportsConditionalBreakpoints' is true.
+   * <p>
+   * This is an optional property.
+   */
+  public void setCondition(final String condition) {
+    this.condition = condition;
+  }
+  
+  /**
+   * An optional expression that controls how many hits of the breakpoint are ignored.
+   * <p>
+   * The backend is expected to interpret the expression as needed.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportsHitConditionalBreakpoints' is true.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getHitCondition() {
+    return this.hitCondition;
+  }
+  
+  /**
+   * An optional expression that controls how many hits of the breakpoint are ignored.
+   * <p>
+   * The backend is expected to interpret the expression as needed.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportsHitConditionalBreakpoints' is true.
+   * <p>
+   * This is an optional property.
+   */
+  public void setHitCondition(final String hitCondition) {
+    this.hitCondition = hitCondition;
+  }
+  
+  /**
+   * If this attribute exists and is non-empty, the backend must not 'break' (stop)
+   * <p>
+   * but log the message instead. Expressions within {} are interpolated.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportsLogPoints' is true.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getLogMessage() {
+    return this.logMessage;
+  }
+  
+  /**
+   * If this attribute exists and is non-empty, the backend must not 'break' (stop)
+   * <p>
+   * but log the message instead. Expressions within {} are interpolated.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportsLogPoints' is true.
+   * <p>
+   * This is an optional property.
+   */
+  public void setLogMessage(final String logMessage) {
+    this.logMessage = logMessage;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("line", this.line);
+    b.add("column", this.column);
+    b.add("condition", this.condition);
+    b.add("hitCondition", this.hitCondition);
+    b.add("logMessage", this.logMessage);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SourceBreakpoint other = (SourceBreakpoint) obj;
+    if (other.line != this.line)
+      return false;
+    if (this.column == null) {
+      if (other.column != null)
+        return false;
+    } else if (!this.column.equals(other.column))
+      return false;
+    if (this.condition == null) {
+      if (other.condition != null)
+        return false;
+    } else if (!this.condition.equals(other.condition))
+      return false;
+    if (this.hitCondition == null) {
+      if (other.hitCondition != null)
+        return false;
+    } else if (!this.hitCondition.equals(other.hitCondition))
+      return false;
+    if (this.logMessage == null) {
+      if (other.logMessage != null)
+        return false;
+    } else if (!this.logMessage.equals(other.logMessage))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + this.line;
+    result = prime * result + ((this.column== null) ? 0 : this.column.hashCode());
+    result = prime * result + ((this.condition== null) ? 0 : this.condition.hashCode());
+    result = prime * result + ((this.hitCondition== null) ? 0 : this.hitCondition.hashCode());
+    return prime * result + ((this.logMessage== null) ? 0 : this.logMessage.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/SourcePresentationHint.java b/java/org/eclipse/lsp4j/debug/SourcePresentationHint.java
new file mode 100644
index 0000000..2043777
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/SourcePresentationHint.java
@@ -0,0 +1,27 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+/**
+ * An optional hint for how to present the source in the UI.
+ * <p>
+ * A value of 'deemphasize' can be used to indicate that the source is not available or that it is skipped on
+ * stepping.
+ */
+@SuppressWarnings("all")
+public enum SourcePresentationHint {
+  NORMAL,
+  
+  EMPHASIZE,
+  
+  DEEMPHASIZE;
+}
diff --git a/java/org/eclipse/lsp4j/debug/SourceResponse.java b/java/org/eclipse/lsp4j/debug/SourceResponse.java
new file mode 100644
index 0000000..4303b68
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/SourceResponse.java
@@ -0,0 +1,112 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Response to 'source' request.
+ */
+@SuppressWarnings("all")
+public class SourceResponse {
+  /**
+   * Content of the source reference.
+   */
+  @NonNull
+  private String content;
+  
+  /**
+   * Optional content type (mime type) of the source.
+   * <p>
+   * This is an optional property.
+   */
+  private String mimeType;
+  
+  /**
+   * Content of the source reference.
+   */
+  @Pure
+  @NonNull
+  public String getContent() {
+    return this.content;
+  }
+  
+  /**
+   * Content of the source reference.
+   */
+  public void setContent(@NonNull final String content) {
+    this.content = Preconditions.checkNotNull(content, "content");
+  }
+  
+  /**
+   * Optional content type (mime type) of the source.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getMimeType() {
+    return this.mimeType;
+  }
+  
+  /**
+   * Optional content type (mime type) of the source.
+   * <p>
+   * This is an optional property.
+   */
+  public void setMimeType(final String mimeType) {
+    this.mimeType = mimeType;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("content", this.content);
+    b.add("mimeType", this.mimeType);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    SourceResponse other = (SourceResponse) obj;
+    if (this.content == null) {
+      if (other.content != null)
+        return false;
+    } else if (!this.content.equals(other.content))
+      return false;
+    if (this.mimeType == null) {
+      if (other.mimeType != null)
+        return false;
+    } else if (!this.mimeType.equals(other.mimeType))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.content== null) ? 0 : this.content.hashCode());
+    return prime * result + ((this.mimeType== null) ? 0 : this.mimeType.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/StackFrame.java b/java/org/eclipse/lsp4j/debug/StackFrame.java
new file mode 100644
index 0000000..696eecb
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/StackFrame.java
@@ -0,0 +1,386 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.Source;
+import org.eclipse.lsp4j.debug.StackFramePresentationHint;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A Stackframe contains the source location.
+ */
+@SuppressWarnings("all")
+public class StackFrame {
+  /**
+   * An identifier for the stack frame. It must be unique across all threads.
+   * <p>
+   * This id can be used to retrieve the scopes of the frame with the 'scopesRequest' or to restart the execution of
+   * a stackframe.
+   */
+  private int id;
+  
+  /**
+   * The name of the stack frame, typically a method name.
+   */
+  @NonNull
+  private String name;
+  
+  /**
+   * The optional source of the frame.
+   * <p>
+   * This is an optional property.
+   */
+  private Source source;
+  
+  /**
+   * The line within the file of the frame. If source is null or doesn't exist, line is 0 and must be ignored.
+   */
+  private int line;
+  
+  /**
+   * The column within the line. If source is null or doesn't exist, column is 0 and must be ignored.
+   */
+  private int column;
+  
+  /**
+   * An optional end line of the range covered by the stack frame.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer endLine;
+  
+  /**
+   * An optional end column of the range covered by the stack frame.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer endColumn;
+  
+  /**
+   * Optional memory reference for the current instruction pointer in this frame.
+   * <p>
+   * This is an optional property.
+   */
+  private String instructionPointerReference;
+  
+  /**
+   * The module associated with this frame, if any.
+   * <p>
+   * This is an optional property.
+   */
+  private Either<Integer, String> moduleId;
+  
+  /**
+   * An optional hint for how to present this frame in the UI.
+   * <p>
+   * A value of 'label' can be used to indicate that the frame is an artificial frame that is used as a visual label
+   * or separator. A value of 'subtle' can be used to change the appearance of a frame in a 'subtle' way.
+   * <p>
+   * This is an optional property.
+   */
+  private StackFramePresentationHint presentationHint;
+  
+  /**
+   * An identifier for the stack frame. It must be unique across all threads.
+   * <p>
+   * This id can be used to retrieve the scopes of the frame with the 'scopesRequest' or to restart the execution of
+   * a stackframe.
+   */
+  @Pure
+  public int getId() {
+    return this.id;
+  }
+  
+  /**
+   * An identifier for the stack frame. It must be unique across all threads.
+   * <p>
+   * This id can be used to retrieve the scopes of the frame with the 'scopesRequest' or to restart the execution of
+   * a stackframe.
+   */
+  public void setId(final int id) {
+    this.id = id;
+  }
+  
+  /**
+   * The name of the stack frame, typically a method name.
+   */
+  @Pure
+  @NonNull
+  public String getName() {
+    return this.name;
+  }
+  
+  /**
+   * The name of the stack frame, typically a method name.
+   */
+  public void setName(@NonNull final String name) {
+    this.name = Preconditions.checkNotNull(name, "name");
+  }
+  
+  /**
+   * The optional source of the frame.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Source getSource() {
+    return this.source;
+  }
+  
+  /**
+   * The optional source of the frame.
+   * <p>
+   * This is an optional property.
+   */
+  public void setSource(final Source source) {
+    this.source = source;
+  }
+  
+  /**
+   * The line within the file of the frame. If source is null or doesn't exist, line is 0 and must be ignored.
+   */
+  @Pure
+  public int getLine() {
+    return this.line;
+  }
+  
+  /**
+   * The line within the file of the frame. If source is null or doesn't exist, line is 0 and must be ignored.
+   */
+  public void setLine(final int line) {
+    this.line = line;
+  }
+  
+  /**
+   * The column within the line. If source is null or doesn't exist, column is 0 and must be ignored.
+   */
+  @Pure
+  public int getColumn() {
+    return this.column;
+  }
+  
+  /**
+   * The column within the line. If source is null or doesn't exist, column is 0 and must be ignored.
+   */
+  public void setColumn(final int column) {
+    this.column = column;
+  }
+  
+  /**
+   * An optional end line of the range covered by the stack frame.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getEndLine() {
+    return this.endLine;
+  }
+  
+  /**
+   * An optional end line of the range covered by the stack frame.
+   * <p>
+   * This is an optional property.
+   */
+  public void setEndLine(final Integer endLine) {
+    this.endLine = endLine;
+  }
+  
+  /**
+   * An optional end column of the range covered by the stack frame.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getEndColumn() {
+    return this.endColumn;
+  }
+  
+  /**
+   * An optional end column of the range covered by the stack frame.
+   * <p>
+   * This is an optional property.
+   */
+  public void setEndColumn(final Integer endColumn) {
+    this.endColumn = endColumn;
+  }
+  
+  /**
+   * Optional memory reference for the current instruction pointer in this frame.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getInstructionPointerReference() {
+    return this.instructionPointerReference;
+  }
+  
+  /**
+   * Optional memory reference for the current instruction pointer in this frame.
+   * <p>
+   * This is an optional property.
+   */
+  public void setInstructionPointerReference(final String instructionPointerReference) {
+    this.instructionPointerReference = instructionPointerReference;
+  }
+  
+  /**
+   * The module associated with this frame, if any.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Either<Integer, String> getModuleId() {
+    return this.moduleId;
+  }
+  
+  /**
+   * The module associated with this frame, if any.
+   * <p>
+   * This is an optional property.
+   */
+  public void setModuleId(final Either<Integer, String> moduleId) {
+    this.moduleId = moduleId;
+  }
+  
+  public void setModuleId(final Integer moduleId) {
+    if (moduleId == null) {
+      this.moduleId = null;
+      return;
+    }
+    this.moduleId = Either.forLeft(moduleId);
+  }
+  
+  public void setModuleId(final String moduleId) {
+    if (moduleId == null) {
+      this.moduleId = null;
+      return;
+    }
+    this.moduleId = Either.forRight(moduleId);
+  }
+  
+  /**
+   * An optional hint for how to present this frame in the UI.
+   * <p>
+   * A value of 'label' can be used to indicate that the frame is an artificial frame that is used as a visual label
+   * or separator. A value of 'subtle' can be used to change the appearance of a frame in a 'subtle' way.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public StackFramePresentationHint getPresentationHint() {
+    return this.presentationHint;
+  }
+  
+  /**
+   * An optional hint for how to present this frame in the UI.
+   * <p>
+   * A value of 'label' can be used to indicate that the frame is an artificial frame that is used as a visual label
+   * or separator. A value of 'subtle' can be used to change the appearance of a frame in a 'subtle' way.
+   * <p>
+   * This is an optional property.
+   */
+  public void setPresentationHint(final StackFramePresentationHint presentationHint) {
+    this.presentationHint = presentationHint;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("id", this.id);
+    b.add("name", this.name);
+    b.add("source", this.source);
+    b.add("line", this.line);
+    b.add("column", this.column);
+    b.add("endLine", this.endLine);
+    b.add("endColumn", this.endColumn);
+    b.add("instructionPointerReference", this.instructionPointerReference);
+    b.add("moduleId", this.moduleId);
+    b.add("presentationHint", this.presentationHint);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    StackFrame other = (StackFrame) obj;
+    if (other.id != this.id)
+      return false;
+    if (this.name == null) {
+      if (other.name != null)
+        return false;
+    } else if (!this.name.equals(other.name))
+      return false;
+    if (this.source == null) {
+      if (other.source != null)
+        return false;
+    } else if (!this.source.equals(other.source))
+      return false;
+    if (other.line != this.line)
+      return false;
+    if (other.column != this.column)
+      return false;
+    if (this.endLine == null) {
+      if (other.endLine != null)
+        return false;
+    } else if (!this.endLine.equals(other.endLine))
+      return false;
+    if (this.endColumn == null) {
+      if (other.endColumn != null)
+        return false;
+    } else if (!this.endColumn.equals(other.endColumn))
+      return false;
+    if (this.instructionPointerReference == null) {
+      if (other.instructionPointerReference != null)
+        return false;
+    } else if (!this.instructionPointerReference.equals(other.instructionPointerReference))
+      return false;
+    if (this.moduleId == null) {
+      if (other.moduleId != null)
+        return false;
+    } else if (!this.moduleId.equals(other.moduleId))
+      return false;
+    if (this.presentationHint == null) {
+      if (other.presentationHint != null)
+        return false;
+    } else if (!this.presentationHint.equals(other.presentationHint))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + this.id;
+    result = prime * result + ((this.name== null) ? 0 : this.name.hashCode());
+    result = prime * result + ((this.source== null) ? 0 : this.source.hashCode());
+    result = prime * result + this.line;
+    result = prime * result + this.column;
+    result = prime * result + ((this.endLine== null) ? 0 : this.endLine.hashCode());
+    result = prime * result + ((this.endColumn== null) ? 0 : this.endColumn.hashCode());
+    result = prime * result + ((this.instructionPointerReference== null) ? 0 : this.instructionPointerReference.hashCode());
+    result = prime * result + ((this.moduleId== null) ? 0 : this.moduleId.hashCode());
+    return prime * result + ((this.presentationHint== null) ? 0 : this.presentationHint.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/StackFrameFormat.java b/java/org/eclipse/lsp4j/debug/StackFrameFormat.java
new file mode 100644
index 0000000..6bfb3fe
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/StackFrameFormat.java
@@ -0,0 +1,283 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.ValueFormat;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Provides formatting information for a stack frame.
+ */
+@SuppressWarnings("all")
+public class StackFrameFormat extends ValueFormat {
+  /**
+   * Displays parameters for the stack frame.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean parameters;
+  
+  /**
+   * Displays the types of parameters for the stack frame.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean parameterTypes;
+  
+  /**
+   * Displays the names of parameters for the stack frame.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean parameterNames;
+  
+  /**
+   * Displays the values of parameters for the stack frame.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean parameterValues;
+  
+  /**
+   * Displays the line number of the stack frame.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean line;
+  
+  /**
+   * Displays the module of the stack frame.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean module;
+  
+  /**
+   * Includes all stack frames, including those the debug adapter might otherwise hide.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean includeAll;
+  
+  /**
+   * Displays parameters for the stack frame.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getParameters() {
+    return this.parameters;
+  }
+  
+  /**
+   * Displays parameters for the stack frame.
+   * <p>
+   * This is an optional property.
+   */
+  public void setParameters(final Boolean parameters) {
+    this.parameters = parameters;
+  }
+  
+  /**
+   * Displays the types of parameters for the stack frame.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getParameterTypes() {
+    return this.parameterTypes;
+  }
+  
+  /**
+   * Displays the types of parameters for the stack frame.
+   * <p>
+   * This is an optional property.
+   */
+  public void setParameterTypes(final Boolean parameterTypes) {
+    this.parameterTypes = parameterTypes;
+  }
+  
+  /**
+   * Displays the names of parameters for the stack frame.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getParameterNames() {
+    return this.parameterNames;
+  }
+  
+  /**
+   * Displays the names of parameters for the stack frame.
+   * <p>
+   * This is an optional property.
+   */
+  public void setParameterNames(final Boolean parameterNames) {
+    this.parameterNames = parameterNames;
+  }
+  
+  /**
+   * Displays the values of parameters for the stack frame.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getParameterValues() {
+    return this.parameterValues;
+  }
+  
+  /**
+   * Displays the values of parameters for the stack frame.
+   * <p>
+   * This is an optional property.
+   */
+  public void setParameterValues(final Boolean parameterValues) {
+    this.parameterValues = parameterValues;
+  }
+  
+  /**
+   * Displays the line number of the stack frame.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getLine() {
+    return this.line;
+  }
+  
+  /**
+   * Displays the line number of the stack frame.
+   * <p>
+   * This is an optional property.
+   */
+  public void setLine(final Boolean line) {
+    this.line = line;
+  }
+  
+  /**
+   * Displays the module of the stack frame.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getModule() {
+    return this.module;
+  }
+  
+  /**
+   * Displays the module of the stack frame.
+   * <p>
+   * This is an optional property.
+   */
+  public void setModule(final Boolean module) {
+    this.module = module;
+  }
+  
+  /**
+   * Includes all stack frames, including those the debug adapter might otherwise hide.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getIncludeAll() {
+    return this.includeAll;
+  }
+  
+  /**
+   * Includes all stack frames, including those the debug adapter might otherwise hide.
+   * <p>
+   * This is an optional property.
+   */
+  public void setIncludeAll(final Boolean includeAll) {
+    this.includeAll = includeAll;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("parameters", this.parameters);
+    b.add("parameterTypes", this.parameterTypes);
+    b.add("parameterNames", this.parameterNames);
+    b.add("parameterValues", this.parameterValues);
+    b.add("line", this.line);
+    b.add("module", this.module);
+    b.add("includeAll", this.includeAll);
+    b.add("hex", getHex());
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    if (!super.equals(obj))
+      return false;
+    StackFrameFormat other = (StackFrameFormat) obj;
+    if (this.parameters == null) {
+      if (other.parameters != null)
+        return false;
+    } else if (!this.parameters.equals(other.parameters))
+      return false;
+    if (this.parameterTypes == null) {
+      if (other.parameterTypes != null)
+        return false;
+    } else if (!this.parameterTypes.equals(other.parameterTypes))
+      return false;
+    if (this.parameterNames == null) {
+      if (other.parameterNames != null)
+        return false;
+    } else if (!this.parameterNames.equals(other.parameterNames))
+      return false;
+    if (this.parameterValues == null) {
+      if (other.parameterValues != null)
+        return false;
+    } else if (!this.parameterValues.equals(other.parameterValues))
+      return false;
+    if (this.line == null) {
+      if (other.line != null)
+        return false;
+    } else if (!this.line.equals(other.line))
+      return false;
+    if (this.module == null) {
+      if (other.module != null)
+        return false;
+    } else if (!this.module.equals(other.module))
+      return false;
+    if (this.includeAll == null) {
+      if (other.includeAll != null)
+        return false;
+    } else if (!this.includeAll.equals(other.includeAll))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + ((this.parameters== null) ? 0 : this.parameters.hashCode());
+    result = prime * result + ((this.parameterTypes== null) ? 0 : this.parameterTypes.hashCode());
+    result = prime * result + ((this.parameterNames== null) ? 0 : this.parameterNames.hashCode());
+    result = prime * result + ((this.parameterValues== null) ? 0 : this.parameterValues.hashCode());
+    result = prime * result + ((this.line== null) ? 0 : this.line.hashCode());
+    result = prime * result + ((this.module== null) ? 0 : this.module.hashCode());
+    return prime * result + ((this.includeAll== null) ? 0 : this.includeAll.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/StackFramePresentationHint.java b/java/org/eclipse/lsp4j/debug/StackFramePresentationHint.java
new file mode 100644
index 0000000..3cd726c
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/StackFramePresentationHint.java
@@ -0,0 +1,27 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+/**
+ * An optional hint for how to present this frame in the UI.
+ * <p>
+ * A value of 'label' can be used to indicate that the frame is an artificial frame that is used as a visual label
+ * or separator. A value of 'subtle' can be used to change the appearance of a frame in a 'subtle' way.
+ */
+@SuppressWarnings("all")
+public enum StackFramePresentationHint {
+  NORMAL,
+  
+  LABEL,
+  
+  SUBTLE;
+}
diff --git a/java/org/eclipse/lsp4j/debug/StackTraceArguments.java b/java/org/eclipse/lsp4j/debug/StackTraceArguments.java
new file mode 100644
index 0000000..46ed37e
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/StackTraceArguments.java
@@ -0,0 +1,178 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.StackFrameFormat;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'stackTrace' request.
+ */
+@SuppressWarnings("all")
+public class StackTraceArguments {
+  /**
+   * Retrieve the stacktrace for this thread.
+   */
+  private int threadId;
+  
+  /**
+   * The index of the first frame to return; if omitted frames start at 0.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer startFrame;
+  
+  /**
+   * The maximum number of frames to return. If levels is not specified or 0, all frames are returned.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer levels;
+  
+  /**
+   * Specifies details on how to format the stack frames.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportsValueFormattingOptions' is true.
+   * <p>
+   * This is an optional property.
+   */
+  private StackFrameFormat format;
+  
+  /**
+   * Retrieve the stacktrace for this thread.
+   */
+  @Pure
+  public int getThreadId() {
+    return this.threadId;
+  }
+  
+  /**
+   * Retrieve the stacktrace for this thread.
+   */
+  public void setThreadId(final int threadId) {
+    this.threadId = threadId;
+  }
+  
+  /**
+   * The index of the first frame to return; if omitted frames start at 0.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getStartFrame() {
+    return this.startFrame;
+  }
+  
+  /**
+   * The index of the first frame to return; if omitted frames start at 0.
+   * <p>
+   * This is an optional property.
+   */
+  public void setStartFrame(final Integer startFrame) {
+    this.startFrame = startFrame;
+  }
+  
+  /**
+   * The maximum number of frames to return. If levels is not specified or 0, all frames are returned.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getLevels() {
+    return this.levels;
+  }
+  
+  /**
+   * The maximum number of frames to return. If levels is not specified or 0, all frames are returned.
+   * <p>
+   * This is an optional property.
+   */
+  public void setLevels(final Integer levels) {
+    this.levels = levels;
+  }
+  
+  /**
+   * Specifies details on how to format the stack frames.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportsValueFormattingOptions' is true.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public StackFrameFormat getFormat() {
+    return this.format;
+  }
+  
+  /**
+   * Specifies details on how to format the stack frames.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportsValueFormattingOptions' is true.
+   * <p>
+   * This is an optional property.
+   */
+  public void setFormat(final StackFrameFormat format) {
+    this.format = format;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("threadId", this.threadId);
+    b.add("startFrame", this.startFrame);
+    b.add("levels", this.levels);
+    b.add("format", this.format);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    StackTraceArguments other = (StackTraceArguments) obj;
+    if (other.threadId != this.threadId)
+      return false;
+    if (this.startFrame == null) {
+      if (other.startFrame != null)
+        return false;
+    } else if (!this.startFrame.equals(other.startFrame))
+      return false;
+    if (this.levels == null) {
+      if (other.levels != null)
+        return false;
+    } else if (!this.levels.equals(other.levels))
+      return false;
+    if (this.format == null) {
+      if (other.format != null)
+        return false;
+    } else if (!this.format.equals(other.format))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + this.threadId;
+    result = prime * result + ((this.startFrame== null) ? 0 : this.startFrame.hashCode());
+    result = prime * result + ((this.levels== null) ? 0 : this.levels.hashCode());
+    return prime * result + ((this.format== null) ? 0 : this.format.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/StackTraceResponse.java b/java/org/eclipse/lsp4j/debug/StackTraceResponse.java
new file mode 100644
index 0000000..61a97b9
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/StackTraceResponse.java
@@ -0,0 +1,129 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.lsp4j.debug.StackFrame;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Response to 'stackTrace' request.
+ */
+@SuppressWarnings("all")
+public class StackTraceResponse {
+  /**
+   * The frames of the stackframe. If the array has length zero, there are no stackframes available.
+   * <p>
+   * This means that there is no location information available.
+   */
+  @NonNull
+  private StackFrame[] stackFrames;
+  
+  /**
+   * The total number of frames available in the stack. If omitted or if totalFrames is larger than the available
+   * frames, a client is expected to request frames until a request returns less frames than requested (which
+   * indicates the end of the stack). Returning monotonically increasing totalFrames values for subsequent requests
+   * can be used to enforce paging in the client.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer totalFrames;
+  
+  /**
+   * The frames of the stackframe. If the array has length zero, there are no stackframes available.
+   * <p>
+   * This means that there is no location information available.
+   */
+  @Pure
+  @NonNull
+  public StackFrame[] getStackFrames() {
+    return this.stackFrames;
+  }
+  
+  /**
+   * The frames of the stackframe. If the array has length zero, there are no stackframes available.
+   * <p>
+   * This means that there is no location information available.
+   */
+  public void setStackFrames(@NonNull final StackFrame[] stackFrames) {
+    this.stackFrames = Preconditions.checkNotNull(stackFrames, "stackFrames");
+  }
+  
+  /**
+   * The total number of frames available in the stack. If omitted or if totalFrames is larger than the available
+   * frames, a client is expected to request frames until a request returns less frames than requested (which
+   * indicates the end of the stack). Returning monotonically increasing totalFrames values for subsequent requests
+   * can be used to enforce paging in the client.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getTotalFrames() {
+    return this.totalFrames;
+  }
+  
+  /**
+   * The total number of frames available in the stack. If omitted or if totalFrames is larger than the available
+   * frames, a client is expected to request frames until a request returns less frames than requested (which
+   * indicates the end of the stack). Returning monotonically increasing totalFrames values for subsequent requests
+   * can be used to enforce paging in the client.
+   * <p>
+   * This is an optional property.
+   */
+  public void setTotalFrames(final Integer totalFrames) {
+    this.totalFrames = totalFrames;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("stackFrames", this.stackFrames);
+    b.add("totalFrames", this.totalFrames);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    StackTraceResponse other = (StackTraceResponse) obj;
+    if (this.stackFrames == null) {
+      if (other.stackFrames != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.stackFrames, other.stackFrames))
+      return false;
+    if (this.totalFrames == null) {
+      if (other.totalFrames != null)
+        return false;
+    } else if (!this.totalFrames.equals(other.totalFrames))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.stackFrames== null) ? 0 : Arrays.deepHashCode(this.stackFrames));
+    return prime * result + ((this.totalFrames== null) ? 0 : this.totalFrames.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/StepBackArguments.java b/java/org/eclipse/lsp4j/debug/StepBackArguments.java
new file mode 100644
index 0000000..46444bf
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/StepBackArguments.java
@@ -0,0 +1,106 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.SteppingGranularity;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'stepBack' request.
+ */
+@SuppressWarnings("all")
+public class StepBackArguments {
+  /**
+   * Execute 'stepBack' for this thread.
+   */
+  private int threadId;
+  
+  /**
+   * Optional granularity to step. If no granularity is specified, a granularity of 'statement' is assumed.
+   * <p>
+   * This is an optional property.
+   */
+  private SteppingGranularity granularity;
+  
+  /**
+   * Execute 'stepBack' for this thread.
+   */
+  @Pure
+  public int getThreadId() {
+    return this.threadId;
+  }
+  
+  /**
+   * Execute 'stepBack' for this thread.
+   */
+  public void setThreadId(final int threadId) {
+    this.threadId = threadId;
+  }
+  
+  /**
+   * Optional granularity to step. If no granularity is specified, a granularity of 'statement' is assumed.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public SteppingGranularity getGranularity() {
+    return this.granularity;
+  }
+  
+  /**
+   * Optional granularity to step. If no granularity is specified, a granularity of 'statement' is assumed.
+   * <p>
+   * This is an optional property.
+   */
+  public void setGranularity(final SteppingGranularity granularity) {
+    this.granularity = granularity;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("threadId", this.threadId);
+    b.add("granularity", this.granularity);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    StepBackArguments other = (StepBackArguments) obj;
+    if (other.threadId != this.threadId)
+      return false;
+    if (this.granularity == null) {
+      if (other.granularity != null)
+        return false;
+    } else if (!this.granularity.equals(other.granularity))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + this.threadId;
+    return prime * result + ((this.granularity== null) ? 0 : this.granularity.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/StepInArguments.java b/java/org/eclipse/lsp4j/debug/StepInArguments.java
new file mode 100644
index 0000000..8d902fb
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/StepInArguments.java
@@ -0,0 +1,139 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.SteppingGranularity;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'stepIn' request.
+ */
+@SuppressWarnings("all")
+public class StepInArguments {
+  /**
+   * Execute 'stepIn' for this thread.
+   */
+  private int threadId;
+  
+  /**
+   * Optional id of the target to step into.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer targetId;
+  
+  /**
+   * Optional granularity to step. If no granularity is specified, a granularity of 'statement' is assumed.
+   * <p>
+   * This is an optional property.
+   */
+  private SteppingGranularity granularity;
+  
+  /**
+   * Execute 'stepIn' for this thread.
+   */
+  @Pure
+  public int getThreadId() {
+    return this.threadId;
+  }
+  
+  /**
+   * Execute 'stepIn' for this thread.
+   */
+  public void setThreadId(final int threadId) {
+    this.threadId = threadId;
+  }
+  
+  /**
+   * Optional id of the target to step into.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getTargetId() {
+    return this.targetId;
+  }
+  
+  /**
+   * Optional id of the target to step into.
+   * <p>
+   * This is an optional property.
+   */
+  public void setTargetId(final Integer targetId) {
+    this.targetId = targetId;
+  }
+  
+  /**
+   * Optional granularity to step. If no granularity is specified, a granularity of 'statement' is assumed.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public SteppingGranularity getGranularity() {
+    return this.granularity;
+  }
+  
+  /**
+   * Optional granularity to step. If no granularity is specified, a granularity of 'statement' is assumed.
+   * <p>
+   * This is an optional property.
+   */
+  public void setGranularity(final SteppingGranularity granularity) {
+    this.granularity = granularity;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("threadId", this.threadId);
+    b.add("targetId", this.targetId);
+    b.add("granularity", this.granularity);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    StepInArguments other = (StepInArguments) obj;
+    if (other.threadId != this.threadId)
+      return false;
+    if (this.targetId == null) {
+      if (other.targetId != null)
+        return false;
+    } else if (!this.targetId.equals(other.targetId))
+      return false;
+    if (this.granularity == null) {
+      if (other.granularity != null)
+        return false;
+    } else if (!this.granularity.equals(other.granularity))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + this.threadId;
+    result = prime * result + ((this.targetId== null) ? 0 : this.targetId.hashCode());
+    return prime * result + ((this.granularity== null) ? 0 : this.granularity.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/StepInTarget.java b/java/org/eclipse/lsp4j/debug/StepInTarget.java
new file mode 100644
index 0000000..d02f201
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/StepInTarget.java
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A StepInTarget can be used in the 'stepIn' request and determines into which single target the stepIn request
+ * should step.
+ */
+@SuppressWarnings("all")
+public class StepInTarget {
+  /**
+   * Unique identifier for a stepIn target.
+   */
+  private int id;
+  
+  /**
+   * The name of the stepIn target (shown in the UI).
+   */
+  @NonNull
+  private String label;
+  
+  /**
+   * Unique identifier for a stepIn target.
+   */
+  @Pure
+  public int getId() {
+    return this.id;
+  }
+  
+  /**
+   * Unique identifier for a stepIn target.
+   */
+  public void setId(final int id) {
+    this.id = id;
+  }
+  
+  /**
+   * The name of the stepIn target (shown in the UI).
+   */
+  @Pure
+  @NonNull
+  public String getLabel() {
+    return this.label;
+  }
+  
+  /**
+   * The name of the stepIn target (shown in the UI).
+   */
+  public void setLabel(@NonNull final String label) {
+    this.label = Preconditions.checkNotNull(label, "label");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("id", this.id);
+    b.add("label", this.label);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    StepInTarget other = (StepInTarget) obj;
+    if (other.id != this.id)
+      return false;
+    if (this.label == null) {
+      if (other.label != null)
+        return false;
+    } else if (!this.label.equals(other.label))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + this.id;
+    return prime * result + ((this.label== null) ? 0 : this.label.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/StepInTargetsArguments.java b/java/org/eclipse/lsp4j/debug/StepInTargetsArguments.java
new file mode 100644
index 0000000..7c4cfdf
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/StepInTargetsArguments.java
@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'stepInTargets' request.
+ */
+@SuppressWarnings("all")
+public class StepInTargetsArguments {
+  /**
+   * The stack frame for which to retrieve the possible stepIn targets.
+   */
+  private int frameId;
+  
+  /**
+   * The stack frame for which to retrieve the possible stepIn targets.
+   */
+  @Pure
+  public int getFrameId() {
+    return this.frameId;
+  }
+  
+  /**
+   * The stack frame for which to retrieve the possible stepIn targets.
+   */
+  public void setFrameId(final int frameId) {
+    this.frameId = frameId;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("frameId", this.frameId);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    StepInTargetsArguments other = (StepInTargetsArguments) obj;
+    if (other.frameId != this.frameId)
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + this.frameId;
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/StepInTargetsResponse.java b/java/org/eclipse/lsp4j/debug/StepInTargetsResponse.java
new file mode 100644
index 0000000..aefbcc9
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/StepInTargetsResponse.java
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.lsp4j.debug.StepInTarget;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Response to 'stepInTargets' request.
+ */
+@SuppressWarnings("all")
+public class StepInTargetsResponse {
+  /**
+   * The possible stepIn targets of the specified source location.
+   */
+  @NonNull
+  private StepInTarget[] targets;
+  
+  /**
+   * The possible stepIn targets of the specified source location.
+   */
+  @Pure
+  @NonNull
+  public StepInTarget[] getTargets() {
+    return this.targets;
+  }
+  
+  /**
+   * The possible stepIn targets of the specified source location.
+   */
+  public void setTargets(@NonNull final StepInTarget[] targets) {
+    this.targets = Preconditions.checkNotNull(targets, "targets");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("targets", this.targets);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    StepInTargetsResponse other = (StepInTargetsResponse) obj;
+    if (this.targets == null) {
+      if (other.targets != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.targets, other.targets))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.targets== null) ? 0 : Arrays.deepHashCode(this.targets));
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/StepOutArguments.java b/java/org/eclipse/lsp4j/debug/StepOutArguments.java
new file mode 100644
index 0000000..01bd701
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/StepOutArguments.java
@@ -0,0 +1,106 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.SteppingGranularity;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'stepOut' request.
+ */
+@SuppressWarnings("all")
+public class StepOutArguments {
+  /**
+   * Execute 'stepOut' for this thread.
+   */
+  private int threadId;
+  
+  /**
+   * Optional granularity to step. If no granularity is specified, a granularity of 'statement' is assumed.
+   * <p>
+   * This is an optional property.
+   */
+  private SteppingGranularity granularity;
+  
+  /**
+   * Execute 'stepOut' for this thread.
+   */
+  @Pure
+  public int getThreadId() {
+    return this.threadId;
+  }
+  
+  /**
+   * Execute 'stepOut' for this thread.
+   */
+  public void setThreadId(final int threadId) {
+    this.threadId = threadId;
+  }
+  
+  /**
+   * Optional granularity to step. If no granularity is specified, a granularity of 'statement' is assumed.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public SteppingGranularity getGranularity() {
+    return this.granularity;
+  }
+  
+  /**
+   * Optional granularity to step. If no granularity is specified, a granularity of 'statement' is assumed.
+   * <p>
+   * This is an optional property.
+   */
+  public void setGranularity(final SteppingGranularity granularity) {
+    this.granularity = granularity;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("threadId", this.threadId);
+    b.add("granularity", this.granularity);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    StepOutArguments other = (StepOutArguments) obj;
+    if (other.threadId != this.threadId)
+      return false;
+    if (this.granularity == null) {
+      if (other.granularity != null)
+        return false;
+    } else if (!this.granularity.equals(other.granularity))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + this.threadId;
+    return prime * result + ((this.granularity== null) ? 0 : this.granularity.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/SteppingGranularity.java b/java/org/eclipse/lsp4j/debug/SteppingGranularity.java
new file mode 100644
index 0000000..4385a9a
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/SteppingGranularity.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+/**
+ * The granularity of one 'step' in the stepping requests 'next', 'stepIn', 'stepOut', and 'stepBack'.
+ */
+@SuppressWarnings("all")
+public enum SteppingGranularity {
+  /**
+   * The step should allow the program to run until the current statement has finished executing.
+   * The meaning of a
+   * statement is determined by the adapter and it may be considered equivalent to a line.
+   * For example 'for(int i =
+   * 0; i &lt; 10; i++) could be considered to have 3 statements 'int i = 0', 'i &lt; 10', and 'i++'.
+   */
+  STATEMENT,
+  
+  /**
+   * The step should allow the program to run until the current source line has executed.
+   */
+  LINE,
+  
+  /**
+   * The step should allow one instruction to execute (e.g. one x86 instruction).
+   */
+  INSTRUCTION;
+}
diff --git a/java/org/eclipse/lsp4j/debug/StoppedEventArguments.java b/java/org/eclipse/lsp4j/debug/StoppedEventArguments.java
new file mode 100644
index 0000000..bf74eac
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/StoppedEventArguments.java
@@ -0,0 +1,283 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The event indicates that the execution of the debuggee has stopped due to some condition.
+ * <p>
+ * This can be caused by a break point previously set, a stepping request has completed, by executing a debugger
+ * statement etc.
+ */
+@SuppressWarnings("all")
+public class StoppedEventArguments {
+  /**
+   * The reason for the event.
+   * <p>
+   * For backward compatibility this string is shown in the UI if the 'description' attribute is missing (but it
+   * must not be translated).
+   * <p>
+   * Possible values include - but not limited to those defined in {@link StoppedEventArgumentsReason}
+   */
+  @NonNull
+  private String reason;
+  
+  /**
+   * The full reason for the event, e.g. 'Paused on exception'. This string is shown in the UI as is and must be
+   * translated.
+   * <p>
+   * This is an optional property.
+   */
+  private String description;
+  
+  /**
+   * The thread which was stopped.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer threadId;
+  
+  /**
+   * A value of true hints to the frontend that this event should not change the focus.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean preserveFocusHint;
+  
+  /**
+   * Additional information. E.g. if reason is 'exception', text contains the exception name. This string is shown
+   * in the UI.
+   * <p>
+   * This is an optional property.
+   */
+  private String text;
+  
+  /**
+   * If 'allThreadsStopped' is true, a debug adapter can announce that all threads have stopped.
+   * <ul>
+   * <li>The client should use this information to enable that all threads can be expanded to access their
+   * stacktraces.</li>
+   * <li>If the attribute is missing or false, only the thread with the given threadId can be expanded.</li>
+   * </ul>
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean allThreadsStopped;
+  
+  /**
+   * The reason for the event.
+   * <p>
+   * For backward compatibility this string is shown in the UI if the 'description' attribute is missing (but it
+   * must not be translated).
+   * <p>
+   * Possible values include - but not limited to those defined in {@link StoppedEventArgumentsReason}
+   */
+  @Pure
+  @NonNull
+  public String getReason() {
+    return this.reason;
+  }
+  
+  /**
+   * The reason for the event.
+   * <p>
+   * For backward compatibility this string is shown in the UI if the 'description' attribute is missing (but it
+   * must not be translated).
+   * <p>
+   * Possible values include - but not limited to those defined in {@link StoppedEventArgumentsReason}
+   */
+  public void setReason(@NonNull final String reason) {
+    this.reason = Preconditions.checkNotNull(reason, "reason");
+  }
+  
+  /**
+   * The full reason for the event, e.g. 'Paused on exception'. This string is shown in the UI as is and must be
+   * translated.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getDescription() {
+    return this.description;
+  }
+  
+  /**
+   * The full reason for the event, e.g. 'Paused on exception'. This string is shown in the UI as is and must be
+   * translated.
+   * <p>
+   * This is an optional property.
+   */
+  public void setDescription(final String description) {
+    this.description = description;
+  }
+  
+  /**
+   * The thread which was stopped.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getThreadId() {
+    return this.threadId;
+  }
+  
+  /**
+   * The thread which was stopped.
+   * <p>
+   * This is an optional property.
+   */
+  public void setThreadId(final Integer threadId) {
+    this.threadId = threadId;
+  }
+  
+  /**
+   * A value of true hints to the frontend that this event should not change the focus.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getPreserveFocusHint() {
+    return this.preserveFocusHint;
+  }
+  
+  /**
+   * A value of true hints to the frontend that this event should not change the focus.
+   * <p>
+   * This is an optional property.
+   */
+  public void setPreserveFocusHint(final Boolean preserveFocusHint) {
+    this.preserveFocusHint = preserveFocusHint;
+  }
+  
+  /**
+   * Additional information. E.g. if reason is 'exception', text contains the exception name. This string is shown
+   * in the UI.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getText() {
+    return this.text;
+  }
+  
+  /**
+   * Additional information. E.g. if reason is 'exception', text contains the exception name. This string is shown
+   * in the UI.
+   * <p>
+   * This is an optional property.
+   */
+  public void setText(final String text) {
+    this.text = text;
+  }
+  
+  /**
+   * If 'allThreadsStopped' is true, a debug adapter can announce that all threads have stopped.
+   * <ul>
+   * <li>The client should use this information to enable that all threads can be expanded to access their
+   * stacktraces.</li>
+   * <li>If the attribute is missing or false, only the thread with the given threadId can be expanded.</li>
+   * </ul>
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getAllThreadsStopped() {
+    return this.allThreadsStopped;
+  }
+  
+  /**
+   * If 'allThreadsStopped' is true, a debug adapter can announce that all threads have stopped.
+   * <ul>
+   * <li>The client should use this information to enable that all threads can be expanded to access their
+   * stacktraces.</li>
+   * <li>If the attribute is missing or false, only the thread with the given threadId can be expanded.</li>
+   * </ul>
+   * <p>
+   * This is an optional property.
+   */
+  public void setAllThreadsStopped(final Boolean allThreadsStopped) {
+    this.allThreadsStopped = allThreadsStopped;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("reason", this.reason);
+    b.add("description", this.description);
+    b.add("threadId", this.threadId);
+    b.add("preserveFocusHint", this.preserveFocusHint);
+    b.add("text", this.text);
+    b.add("allThreadsStopped", this.allThreadsStopped);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    StoppedEventArguments other = (StoppedEventArguments) obj;
+    if (this.reason == null) {
+      if (other.reason != null)
+        return false;
+    } else if (!this.reason.equals(other.reason))
+      return false;
+    if (this.description == null) {
+      if (other.description != null)
+        return false;
+    } else if (!this.description.equals(other.description))
+      return false;
+    if (this.threadId == null) {
+      if (other.threadId != null)
+        return false;
+    } else if (!this.threadId.equals(other.threadId))
+      return false;
+    if (this.preserveFocusHint == null) {
+      if (other.preserveFocusHint != null)
+        return false;
+    } else if (!this.preserveFocusHint.equals(other.preserveFocusHint))
+      return false;
+    if (this.text == null) {
+      if (other.text != null)
+        return false;
+    } else if (!this.text.equals(other.text))
+      return false;
+    if (this.allThreadsStopped == null) {
+      if (other.allThreadsStopped != null)
+        return false;
+    } else if (!this.allThreadsStopped.equals(other.allThreadsStopped))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.reason== null) ? 0 : this.reason.hashCode());
+    result = prime * result + ((this.description== null) ? 0 : this.description.hashCode());
+    result = prime * result + ((this.threadId== null) ? 0 : this.threadId.hashCode());
+    result = prime * result + ((this.preserveFocusHint== null) ? 0 : this.preserveFocusHint.hashCode());
+    result = prime * result + ((this.text== null) ? 0 : this.text.hashCode());
+    return prime * result + ((this.allThreadsStopped== null) ? 0 : this.allThreadsStopped.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/StoppedEventArgumentsReason.java b/java/org/eclipse/lsp4j/debug/StoppedEventArgumentsReason.java
new file mode 100644
index 0000000..0b72e75
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/StoppedEventArgumentsReason.java
@@ -0,0 +1,41 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+/**
+ * The reason for the event.
+ * <p>
+ * For backward compatibility this string is shown in the UI if the 'description' attribute is missing (but it
+ * must not be translated).
+ * <p>
+ * Possible values include - but not limited to those defined in {@link StoppedEventArgumentsReason}
+ */
+@SuppressWarnings("all")
+public interface StoppedEventArgumentsReason {
+  static final String STEP = "step";
+  
+  static final String BREAKPOINT = "breakpoint";
+  
+  static final String EXCEPTION = "exception";
+  
+  static final String PAUSE = "pause";
+  
+  static final String ENTRY = "entry";
+  
+  static final String GOTO = "goto";
+  
+  static final String FUNCTION_BREAKPOINT = "function breakpoint";
+  
+  static final String DATA_BREAKPOINT = "data breakpoint";
+  
+  static final String INSTRUCTION_BREAKPOINT = "instruction breakpoint";
+}
diff --git a/java/org/eclipse/lsp4j/debug/TerminateArguments.java b/java/org/eclipse/lsp4j/debug/TerminateArguments.java
new file mode 100644
index 0000000..1a6e57a
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/TerminateArguments.java
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'terminate' request.
+ */
+@SuppressWarnings("all")
+public class TerminateArguments {
+  /**
+   * A value of true indicates that this 'terminate' request is part of a restart sequence.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean restart;
+  
+  /**
+   * A value of true indicates that this 'terminate' request is part of a restart sequence.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getRestart() {
+    return this.restart;
+  }
+  
+  /**
+   * A value of true indicates that this 'terminate' request is part of a restart sequence.
+   * <p>
+   * This is an optional property.
+   */
+  public void setRestart(final Boolean restart) {
+    this.restart = restart;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("restart", this.restart);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    TerminateArguments other = (TerminateArguments) obj;
+    if (this.restart == null) {
+      if (other.restart != null)
+        return false;
+    } else if (!this.restart.equals(other.restart))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.restart== null) ? 0 : this.restart.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/TerminateThreadsArguments.java b/java/org/eclipse/lsp4j/debug/TerminateThreadsArguments.java
new file mode 100644
index 0000000..a5a9497
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/TerminateThreadsArguments.java
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'terminateThreads' request.
+ */
+@SuppressWarnings("all")
+public class TerminateThreadsArguments {
+  /**
+   * Ids of threads to be terminated.
+   * <p>
+   * This is an optional property.
+   */
+  private int[] threadIds;
+  
+  /**
+   * Ids of threads to be terminated.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public int[] getThreadIds() {
+    return this.threadIds;
+  }
+  
+  /**
+   * Ids of threads to be terminated.
+   * <p>
+   * This is an optional property.
+   */
+  public void setThreadIds(final int[] threadIds) {
+    this.threadIds = threadIds;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("threadIds", this.threadIds);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    TerminateThreadsArguments other = (TerminateThreadsArguments) obj;
+    if (this.threadIds == null) {
+      if (other.threadIds != null)
+        return false;
+    } else if (!Arrays.equals(this.threadIds, other.threadIds))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.threadIds== null) ? 0 : Arrays.hashCode(this.threadIds));
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/TerminatedEventArguments.java b/java/org/eclipse/lsp4j/debug/TerminatedEventArguments.java
new file mode 100644
index 0000000..3721682
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/TerminatedEventArguments.java
@@ -0,0 +1,92 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The event indicates that debugging of the debuggee has terminated. This does **not** mean that the debuggee
+ * itself has exited.
+ */
+@SuppressWarnings("all")
+public class TerminatedEventArguments {
+  /**
+   * A debug adapter may set 'restart' to true (or to an arbitrary object) to request that the front end restarts
+   * the session.
+   * <p>
+   * The value is not interpreted by the client and passed unmodified as an attribute '__restart' to the 'launch'
+   * and 'attach' requests.
+   * <p>
+   * This is an optional property.
+   */
+  private Object restart;
+  
+  /**
+   * A debug adapter may set 'restart' to true (or to an arbitrary object) to request that the front end restarts
+   * the session.
+   * <p>
+   * The value is not interpreted by the client and passed unmodified as an attribute '__restart' to the 'launch'
+   * and 'attach' requests.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Object getRestart() {
+    return this.restart;
+  }
+  
+  /**
+   * A debug adapter may set 'restart' to true (or to an arbitrary object) to request that the front end restarts
+   * the session.
+   * <p>
+   * The value is not interpreted by the client and passed unmodified as an attribute '__restart' to the 'launch'
+   * and 'attach' requests.
+   * <p>
+   * This is an optional property.
+   */
+  public void setRestart(final Object restart) {
+    this.restart = restart;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("restart", this.restart);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    TerminatedEventArguments other = (TerminatedEventArguments) obj;
+    if (this.restart == null) {
+      if (other.restart != null)
+        return false;
+    } else if (!this.restart.equals(other.restart))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.restart== null) ? 0 : this.restart.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/Thread.java b/java/org/eclipse/lsp4j/debug/Thread.java
new file mode 100644
index 0000000..bb976ca
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/Thread.java
@@ -0,0 +1,103 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A Thread
+ */
+@SuppressWarnings("all")
+public class Thread {
+  /**
+   * Unique identifier for the thread.
+   */
+  private int id;
+  
+  /**
+   * A name of the thread.
+   */
+  @NonNull
+  private String name;
+  
+  /**
+   * Unique identifier for the thread.
+   */
+  @Pure
+  public int getId() {
+    return this.id;
+  }
+  
+  /**
+   * Unique identifier for the thread.
+   */
+  public void setId(final int id) {
+    this.id = id;
+  }
+  
+  /**
+   * A name of the thread.
+   */
+  @Pure
+  @NonNull
+  public String getName() {
+    return this.name;
+  }
+  
+  /**
+   * A name of the thread.
+   */
+  public void setName(@NonNull final String name) {
+    this.name = Preconditions.checkNotNull(name, "name");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("id", this.id);
+    b.add("name", this.name);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    Thread other = (Thread) obj;
+    if (other.id != this.id)
+      return false;
+    if (this.name == null) {
+      if (other.name != null)
+        return false;
+    } else if (!this.name.equals(other.name))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + this.id;
+    return prime * result + ((this.name== null) ? 0 : this.name.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ThreadEventArguments.java b/java/org/eclipse/lsp4j/debug/ThreadEventArguments.java
new file mode 100644
index 0000000..9e66cc2
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ThreadEventArguments.java
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * The event indicates that a thread has started or exited.
+ */
+@SuppressWarnings("all")
+public class ThreadEventArguments {
+  /**
+   * The reason for the event.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link ThreadEventArgumentsReason}
+   */
+  @NonNull
+  private String reason;
+  
+  /**
+   * The identifier of the thread.
+   */
+  private int threadId;
+  
+  /**
+   * The reason for the event.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link ThreadEventArgumentsReason}
+   */
+  @Pure
+  @NonNull
+  public String getReason() {
+    return this.reason;
+  }
+  
+  /**
+   * The reason for the event.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link ThreadEventArgumentsReason}
+   */
+  public void setReason(@NonNull final String reason) {
+    this.reason = Preconditions.checkNotNull(reason, "reason");
+  }
+  
+  /**
+   * The identifier of the thread.
+   */
+  @Pure
+  public int getThreadId() {
+    return this.threadId;
+  }
+  
+  /**
+   * The identifier of the thread.
+   */
+  public void setThreadId(final int threadId) {
+    this.threadId = threadId;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("reason", this.reason);
+    b.add("threadId", this.threadId);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ThreadEventArguments other = (ThreadEventArguments) obj;
+    if (this.reason == null) {
+      if (other.reason != null)
+        return false;
+    } else if (!this.reason.equals(other.reason))
+      return false;
+    if (other.threadId != this.threadId)
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.reason== null) ? 0 : this.reason.hashCode());
+    return prime * result + this.threadId;
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ThreadEventArgumentsReason.java b/java/org/eclipse/lsp4j/debug/ThreadEventArgumentsReason.java
new file mode 100644
index 0000000..62e4347
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ThreadEventArgumentsReason.java
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+/**
+ * The reason for the event.
+ * <p>
+ * Possible values include - but not limited to those defined in {@link ThreadEventArgumentsReason}
+ */
+@SuppressWarnings("all")
+public interface ThreadEventArgumentsReason {
+  static final String STARTED = "started";
+  
+  static final String EXITED = "exited";
+}
diff --git a/java/org/eclipse/lsp4j/debug/ThreadsResponse.java b/java/org/eclipse/lsp4j/debug/ThreadsResponse.java
new file mode 100644
index 0000000..6c47565
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ThreadsResponse.java
@@ -0,0 +1,78 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Response to 'threads' request.
+ */
+@SuppressWarnings("all")
+public class ThreadsResponse {
+  /**
+   * All threads.
+   */
+  @NonNull
+  private org.eclipse.lsp4j.debug.Thread[] threads;
+  
+  /**
+   * All threads.
+   */
+  @Pure
+  @NonNull
+  public org.eclipse.lsp4j.debug.Thread[] getThreads() {
+    return this.threads;
+  }
+  
+  /**
+   * All threads.
+   */
+  public void setThreads(@NonNull final org.eclipse.lsp4j.debug.Thread[] threads) {
+    this.threads = Preconditions.checkNotNull(threads, "threads");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("threads", this.threads);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ThreadsResponse other = (ThreadsResponse) obj;
+    if (this.threads == null) {
+      if (other.threads != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.threads, other.threads))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.threads== null) ? 0 : Arrays.deepHashCode(this.threads));
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/ValueFormat.java b/java/org/eclipse/lsp4j/debug/ValueFormat.java
new file mode 100644
index 0000000..c53eb38
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/ValueFormat.java
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Provides formatting information for a value.
+ */
+@SuppressWarnings("all")
+public class ValueFormat {
+  /**
+   * Display the value in hex.
+   * <p>
+   * This is an optional property.
+   */
+  private Boolean hex;
+  
+  /**
+   * Display the value in hex.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Boolean getHex() {
+    return this.hex;
+  }
+  
+  /**
+   * Display the value in hex.
+   * <p>
+   * This is an optional property.
+   */
+  public void setHex(final Boolean hex) {
+    this.hex = hex;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("hex", this.hex);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    ValueFormat other = (ValueFormat) obj;
+    if (this.hex == null) {
+      if (other.hex != null)
+        return false;
+    } else if (!this.hex.equals(other.hex))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.hex== null) ? 0 : this.hex.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/Variable.java b/java/org/eclipse/lsp4j/debug/Variable.java
new file mode 100644
index 0000000..b6e4a55
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/Variable.java
@@ -0,0 +1,384 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.VariablePresentationHint;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * A Variable is a name/value pair.
+ * <p>
+ * Optionally a variable can have a 'type' that is shown if space permits or when hovering over the variable's
+ * name.
+ * <p>
+ * An optional 'kind' is used to render additional properties of the variable, e.g. different icons can be used to
+ * indicate that a variable is public or private.
+ * <p>
+ * If the value is structured (has children), a handle is provided to retrieve the children with the
+ * VariablesRequest.
+ * <p>
+ * If the number of named or indexed children is large, the numbers should be returned via the optional
+ * 'namedVariables' and 'indexedVariables' attributes.
+ * <p>
+ * The client can use this optional information to present the children in a paged UI and fetch them in chunks.
+ */
+@SuppressWarnings("all")
+public class Variable {
+  /**
+   * The variable's name.
+   */
+  @NonNull
+  private String name;
+  
+  /**
+   * The variable's value. This can be a multi-line text, e.g. for a function the body of a function.
+   */
+  @NonNull
+  private String value;
+  
+  /**
+   * The type of the variable's value. Typically shown in the UI when hovering over the value.
+   * <p>
+   * This attribute should only be returned by a debug adapter if the client has passed the value true for the
+   * 'supportsVariableType' capability of the 'initialize' request.
+   * <p>
+   * This is an optional property.
+   */
+  private String type;
+  
+  /**
+   * Properties of a variable that can be used to determine how to render the variable in the UI.
+   * <p>
+   * This is an optional property.
+   */
+  private VariablePresentationHint presentationHint;
+  
+  /**
+   * Optional evaluatable name of this variable which can be passed to the 'EvaluateRequest' to fetch the variable's
+   * value.
+   * <p>
+   * This is an optional property.
+   */
+  private String evaluateName;
+  
+  /**
+   * If variablesReference is &gt; 0, the variable is structured and its children can be retrieved by passing
+   * variablesReference to the VariablesRequest.
+   */
+  private int variablesReference;
+  
+  /**
+   * The number of named child variables.
+   * <p>
+   * The client can use this optional information to present the children in a paged UI and fetch them in chunks.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer namedVariables;
+  
+  /**
+   * The number of indexed child variables.
+   * <p>
+   * The client can use this optional information to present the children in a paged UI and fetch them in chunks.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer indexedVariables;
+  
+  /**
+   * Optional memory reference for the variable if the variable represents executable code, such as a function
+   * pointer.
+   * <p>
+   * This attribute is only required if the client has passed the value true for the 'supportsMemoryReferences'
+   * capability of the 'initialize' request.
+   * <p>
+   * This is an optional property.
+   */
+  private String memoryReference;
+  
+  /**
+   * The variable's name.
+   */
+  @Pure
+  @NonNull
+  public String getName() {
+    return this.name;
+  }
+  
+  /**
+   * The variable's name.
+   */
+  public void setName(@NonNull final String name) {
+    this.name = Preconditions.checkNotNull(name, "name");
+  }
+  
+  /**
+   * The variable's value. This can be a multi-line text, e.g. for a function the body of a function.
+   */
+  @Pure
+  @NonNull
+  public String getValue() {
+    return this.value;
+  }
+  
+  /**
+   * The variable's value. This can be a multi-line text, e.g. for a function the body of a function.
+   */
+  public void setValue(@NonNull final String value) {
+    this.value = Preconditions.checkNotNull(value, "value");
+  }
+  
+  /**
+   * The type of the variable's value. Typically shown in the UI when hovering over the value.
+   * <p>
+   * This attribute should only be returned by a debug adapter if the client has passed the value true for the
+   * 'supportsVariableType' capability of the 'initialize' request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getType() {
+    return this.type;
+  }
+  
+  /**
+   * The type of the variable's value. Typically shown in the UI when hovering over the value.
+   * <p>
+   * This attribute should only be returned by a debug adapter if the client has passed the value true for the
+   * 'supportsVariableType' capability of the 'initialize' request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setType(final String type) {
+    this.type = type;
+  }
+  
+  /**
+   * Properties of a variable that can be used to determine how to render the variable in the UI.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public VariablePresentationHint getPresentationHint() {
+    return this.presentationHint;
+  }
+  
+  /**
+   * Properties of a variable that can be used to determine how to render the variable in the UI.
+   * <p>
+   * This is an optional property.
+   */
+  public void setPresentationHint(final VariablePresentationHint presentationHint) {
+    this.presentationHint = presentationHint;
+  }
+  
+  /**
+   * Optional evaluatable name of this variable which can be passed to the 'EvaluateRequest' to fetch the variable's
+   * value.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getEvaluateName() {
+    return this.evaluateName;
+  }
+  
+  /**
+   * Optional evaluatable name of this variable which can be passed to the 'EvaluateRequest' to fetch the variable's
+   * value.
+   * <p>
+   * This is an optional property.
+   */
+  public void setEvaluateName(final String evaluateName) {
+    this.evaluateName = evaluateName;
+  }
+  
+  /**
+   * If variablesReference is &gt; 0, the variable is structured and its children can be retrieved by passing
+   * variablesReference to the VariablesRequest.
+   */
+  @Pure
+  public int getVariablesReference() {
+    return this.variablesReference;
+  }
+  
+  /**
+   * If variablesReference is &gt; 0, the variable is structured and its children can be retrieved by passing
+   * variablesReference to the VariablesRequest.
+   */
+  public void setVariablesReference(final int variablesReference) {
+    this.variablesReference = variablesReference;
+  }
+  
+  /**
+   * The number of named child variables.
+   * <p>
+   * The client can use this optional information to present the children in a paged UI and fetch them in chunks.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getNamedVariables() {
+    return this.namedVariables;
+  }
+  
+  /**
+   * The number of named child variables.
+   * <p>
+   * The client can use this optional information to present the children in a paged UI and fetch them in chunks.
+   * <p>
+   * This is an optional property.
+   */
+  public void setNamedVariables(final Integer namedVariables) {
+    this.namedVariables = namedVariables;
+  }
+  
+  /**
+   * The number of indexed child variables.
+   * <p>
+   * The client can use this optional information to present the children in a paged UI and fetch them in chunks.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getIndexedVariables() {
+    return this.indexedVariables;
+  }
+  
+  /**
+   * The number of indexed child variables.
+   * <p>
+   * The client can use this optional information to present the children in a paged UI and fetch them in chunks.
+   * <p>
+   * This is an optional property.
+   */
+  public void setIndexedVariables(final Integer indexedVariables) {
+    this.indexedVariables = indexedVariables;
+  }
+  
+  /**
+   * Optional memory reference for the variable if the variable represents executable code, such as a function
+   * pointer.
+   * <p>
+   * This attribute is only required if the client has passed the value true for the 'supportsMemoryReferences'
+   * capability of the 'initialize' request.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public String getMemoryReference() {
+    return this.memoryReference;
+  }
+  
+  /**
+   * Optional memory reference for the variable if the variable represents executable code, such as a function
+   * pointer.
+   * <p>
+   * This attribute is only required if the client has passed the value true for the 'supportsMemoryReferences'
+   * capability of the 'initialize' request.
+   * <p>
+   * This is an optional property.
+   */
+  public void setMemoryReference(final String memoryReference) {
+    this.memoryReference = memoryReference;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("name", this.name);
+    b.add("value", this.value);
+    b.add("type", this.type);
+    b.add("presentationHint", this.presentationHint);
+    b.add("evaluateName", this.evaluateName);
+    b.add("variablesReference", this.variablesReference);
+    b.add("namedVariables", this.namedVariables);
+    b.add("indexedVariables", this.indexedVariables);
+    b.add("memoryReference", this.memoryReference);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    Variable other = (Variable) obj;
+    if (this.name == null) {
+      if (other.name != null)
+        return false;
+    } else if (!this.name.equals(other.name))
+      return false;
+    if (this.value == null) {
+      if (other.value != null)
+        return false;
+    } else if (!this.value.equals(other.value))
+      return false;
+    if (this.type == null) {
+      if (other.type != null)
+        return false;
+    } else if (!this.type.equals(other.type))
+      return false;
+    if (this.presentationHint == null) {
+      if (other.presentationHint != null)
+        return false;
+    } else if (!this.presentationHint.equals(other.presentationHint))
+      return false;
+    if (this.evaluateName == null) {
+      if (other.evaluateName != null)
+        return false;
+    } else if (!this.evaluateName.equals(other.evaluateName))
+      return false;
+    if (other.variablesReference != this.variablesReference)
+      return false;
+    if (this.namedVariables == null) {
+      if (other.namedVariables != null)
+        return false;
+    } else if (!this.namedVariables.equals(other.namedVariables))
+      return false;
+    if (this.indexedVariables == null) {
+      if (other.indexedVariables != null)
+        return false;
+    } else if (!this.indexedVariables.equals(other.indexedVariables))
+      return false;
+    if (this.memoryReference == null) {
+      if (other.memoryReference != null)
+        return false;
+    } else if (!this.memoryReference.equals(other.memoryReference))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.name== null) ? 0 : this.name.hashCode());
+    result = prime * result + ((this.value== null) ? 0 : this.value.hashCode());
+    result = prime * result + ((this.type== null) ? 0 : this.type.hashCode());
+    result = prime * result + ((this.presentationHint== null) ? 0 : this.presentationHint.hashCode());
+    result = prime * result + ((this.evaluateName== null) ? 0 : this.evaluateName.hashCode());
+    result = prime * result + this.variablesReference;
+    result = prime * result + ((this.namedVariables== null) ? 0 : this.namedVariables.hashCode());
+    result = prime * result + ((this.indexedVariables== null) ? 0 : this.indexedVariables.hashCode());
+    return prime * result + ((this.memoryReference== null) ? 0 : this.memoryReference.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/VariablePresentationHint.java b/java/org/eclipse/lsp4j/debug/VariablePresentationHint.java
new file mode 100644
index 0000000..2b8b6fa
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/VariablePresentationHint.java
@@ -0,0 +1,169 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Optional properties of a variable that can be used to determine how to render the variable in the UI.
+ */
+@SuppressWarnings("all")
+public class VariablePresentationHint {
+  /**
+   * The kind of variable. Before introducing additional values, try to use the listed values.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link VariablePresentationHintKind}
+   */
+  private String kind;
+  
+  /**
+   * Set of attributes represented as an array of strings. Before introducing additional values, try to use the
+   * listed values.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link VariablePresentationHintAttributes}
+   */
+  private String[] attributes;
+  
+  /**
+   * Visibility of variable. Before introducing additional values, try to use the listed values.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link VariablePresentationHintVisibility}
+   */
+  private String visibility;
+  
+  /**
+   * The kind of variable. Before introducing additional values, try to use the listed values.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link VariablePresentationHintKind}
+   */
+  @Pure
+  public String getKind() {
+    return this.kind;
+  }
+  
+  /**
+   * The kind of variable. Before introducing additional values, try to use the listed values.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link VariablePresentationHintKind}
+   */
+  public void setKind(final String kind) {
+    this.kind = kind;
+  }
+  
+  /**
+   * Set of attributes represented as an array of strings. Before introducing additional values, try to use the
+   * listed values.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link VariablePresentationHintAttributes}
+   */
+  @Pure
+  public String[] getAttributes() {
+    return this.attributes;
+  }
+  
+  /**
+   * Set of attributes represented as an array of strings. Before introducing additional values, try to use the
+   * listed values.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link VariablePresentationHintAttributes}
+   */
+  public void setAttributes(final String[] attributes) {
+    this.attributes = attributes;
+  }
+  
+  /**
+   * Visibility of variable. Before introducing additional values, try to use the listed values.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link VariablePresentationHintVisibility}
+   */
+  @Pure
+  public String getVisibility() {
+    return this.visibility;
+  }
+  
+  /**
+   * Visibility of variable. Before introducing additional values, try to use the listed values.
+   * <p>
+   * This is an optional property.
+   * <p>
+   * Possible values include - but not limited to those defined in {@link VariablePresentationHintVisibility}
+   */
+  public void setVisibility(final String visibility) {
+    this.visibility = visibility;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("kind", this.kind);
+    b.add("attributes", this.attributes);
+    b.add("visibility", this.visibility);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    VariablePresentationHint other = (VariablePresentationHint) obj;
+    if (this.kind == null) {
+      if (other.kind != null)
+        return false;
+    } else if (!this.kind.equals(other.kind))
+      return false;
+    if (this.attributes == null) {
+      if (other.attributes != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.attributes, other.attributes))
+      return false;
+    if (this.visibility == null) {
+      if (other.visibility != null)
+        return false;
+    } else if (!this.visibility.equals(other.visibility))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((this.kind== null) ? 0 : this.kind.hashCode());
+    result = prime * result + ((this.attributes== null) ? 0 : Arrays.deepHashCode(this.attributes));
+    return prime * result + ((this.visibility== null) ? 0 : this.visibility.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/VariablePresentationHintAttributes.java b/java/org/eclipse/lsp4j/debug/VariablePresentationHintAttributes.java
new file mode 100644
index 0000000..1acfbf5
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/VariablePresentationHintAttributes.java
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+/**
+ * <p>
+ * Possible values include - but not limited to those defined in {@link VariablePresentationHintAttributes}
+ */
+@SuppressWarnings("all")
+public interface VariablePresentationHintAttributes {
+  /**
+   * Indicates that the object is static.
+   */
+  static final String STATIC = "static";
+  
+  /**
+   * Indicates that the object is a constant.
+   */
+  static final String CONSTANT = "constant";
+  
+  /**
+   * Indicates that the object is read only.
+   */
+  static final String READ_ONLY = "readOnly";
+  
+  /**
+   * Indicates that the object is a raw string.
+   */
+  static final String RAW_STRING = "rawString";
+  
+  /**
+   * Indicates that the object can have an Object ID created for it.
+   */
+  static final String HAS_OBJECT_ID = "hasObjectId";
+  
+  /**
+   * Indicates that the object has an Object ID associated with it.
+   */
+  static final String CAN_HAVE_OBJECT_ID = "canHaveObjectId";
+  
+  /**
+   * Indicates that the evaluation had side effects.
+   */
+  static final String HAS_SIDE_EFFECTS = "hasSideEffects";
+  
+  /**
+   * Indicates that the object has its value tracked by a data breakpoint.
+   */
+  static final String HAS_DATA_BREAKPOINT = "hasDataBreakpoint";
+}
diff --git a/java/org/eclipse/lsp4j/debug/VariablePresentationHintKind.java b/java/org/eclipse/lsp4j/debug/VariablePresentationHintKind.java
new file mode 100644
index 0000000..880a287
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/VariablePresentationHintKind.java
@@ -0,0 +1,81 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+/**
+ * The kind of variable. Before introducing additional values, try to use the listed values.
+ * <p>
+ * Possible values include - but not limited to those defined in {@link VariablePresentationHintKind}
+ */
+@SuppressWarnings("all")
+public interface VariablePresentationHintKind {
+  /**
+   * Indicates that the object is a property.
+   */
+  static final String PROPERTY = "property";
+  
+  /**
+   * Indicates that the object is a method.
+   */
+  static final String METHOD = "method";
+  
+  /**
+   * Indicates that the object is a class.
+   */
+  static final String CLASS = "class";
+  
+  /**
+   * Indicates that the object is data.
+   */
+  static final String DATA = "data";
+  
+  /**
+   * Indicates that the object is an event.
+   */
+  static final String EVENT = "event";
+  
+  /**
+   * Indicates that the object is a base class.
+   */
+  static final String BASE_CLASS = "baseClass";
+  
+  /**
+   * Indicates that the object is an inner class.
+   */
+  static final String INNER_CLASS = "innerClass";
+  
+  /**
+   * Indicates that the object is an interface.
+   */
+  static final String INTERFACE = "interface";
+  
+  /**
+   * Indicates that the object is the most derived class.
+   */
+  static final String MOST_DERIVED_CLASS = "mostDerivedClass";
+  
+  /**
+   * Indicates that the object is virtual, that means it is a synthetic object introducedby the
+   * adapter for
+   * rendering purposes, e.g. an index range for large arrays.
+   */
+  static final String VIRTUAL = "virtual";
+  
+  /**
+   * Deprecated: Indicates that a data breakpoint is registered for the object. The 'hasDataBreakpoint' attribute
+   * should generally be used instead.
+   * <p>
+   * @deprecated The 'hasDataBreakpoint' attribute should generally be used instead.
+   */
+  @Deprecated
+  static final String DATA_BREAKPOINT = "dataBreakpoint";
+}
diff --git a/java/org/eclipse/lsp4j/debug/VariablePresentationHintVisibility.java b/java/org/eclipse/lsp4j/debug/VariablePresentationHintVisibility.java
new file mode 100644
index 0000000..f17c68f
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/VariablePresentationHintVisibility.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+/**
+ * Visibility of variable. Before introducing additional values, try to use the listed values.
+ * <p>
+ * Possible values include - but not limited to those defined in {@link VariablePresentationHintVisibility}
+ */
+@SuppressWarnings("all")
+public interface VariablePresentationHintVisibility {
+  static final String PUBLIC = "public";
+  
+  static final String PRIVATE = "private";
+  
+  static final String PROTECTED = "protected";
+  
+  static final String INTERNAL = "internal";
+  
+  static final String FINAL = "final";
+}
diff --git a/java/org/eclipse/lsp4j/debug/VariablesArguments.java b/java/org/eclipse/lsp4j/debug/VariablesArguments.java
new file mode 100644
index 0000000..8fa035d
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/VariablesArguments.java
@@ -0,0 +1,212 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import org.eclipse.lsp4j.debug.ValueFormat;
+import org.eclipse.lsp4j.debug.VariablesArgumentsFilter;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Arguments for 'variables' request.
+ */
+@SuppressWarnings("all")
+public class VariablesArguments {
+  /**
+   * The Variable reference.
+   */
+  private int variablesReference;
+  
+  /**
+   * Optional filter to limit the child variables to either named or indexed. If omitted, both types are fetched.
+   * <p>
+   * This is an optional property.
+   */
+  private VariablesArgumentsFilter filter;
+  
+  /**
+   * The index of the first variable to return; if omitted children start at 0.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer start;
+  
+  /**
+   * The number of variables to return. If count is missing or 0, all variables are returned.
+   * <p>
+   * This is an optional property.
+   */
+  private Integer count;
+  
+  /**
+   * Specifies details on how to format the Variable values.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportsValueFormattingOptions' is true.
+   * <p>
+   * This is an optional property.
+   */
+  private ValueFormat format;
+  
+  /**
+   * The Variable reference.
+   */
+  @Pure
+  public int getVariablesReference() {
+    return this.variablesReference;
+  }
+  
+  /**
+   * The Variable reference.
+   */
+  public void setVariablesReference(final int variablesReference) {
+    this.variablesReference = variablesReference;
+  }
+  
+  /**
+   * Optional filter to limit the child variables to either named or indexed. If omitted, both types are fetched.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public VariablesArgumentsFilter getFilter() {
+    return this.filter;
+  }
+  
+  /**
+   * Optional filter to limit the child variables to either named or indexed. If omitted, both types are fetched.
+   * <p>
+   * This is an optional property.
+   */
+  public void setFilter(final VariablesArgumentsFilter filter) {
+    this.filter = filter;
+  }
+  
+  /**
+   * The index of the first variable to return; if omitted children start at 0.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getStart() {
+    return this.start;
+  }
+  
+  /**
+   * The index of the first variable to return; if omitted children start at 0.
+   * <p>
+   * This is an optional property.
+   */
+  public void setStart(final Integer start) {
+    this.start = start;
+  }
+  
+  /**
+   * The number of variables to return. If count is missing or 0, all variables are returned.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public Integer getCount() {
+    return this.count;
+  }
+  
+  /**
+   * The number of variables to return. If count is missing or 0, all variables are returned.
+   * <p>
+   * This is an optional property.
+   */
+  public void setCount(final Integer count) {
+    this.count = count;
+  }
+  
+  /**
+   * Specifies details on how to format the Variable values.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportsValueFormattingOptions' is true.
+   * <p>
+   * This is an optional property.
+   */
+  @Pure
+  public ValueFormat getFormat() {
+    return this.format;
+  }
+  
+  /**
+   * Specifies details on how to format the Variable values.
+   * <p>
+   * The attribute is only honored by a debug adapter if the capability 'supportsValueFormattingOptions' is true.
+   * <p>
+   * This is an optional property.
+   */
+  public void setFormat(final ValueFormat format) {
+    this.format = format;
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("variablesReference", this.variablesReference);
+    b.add("filter", this.filter);
+    b.add("start", this.start);
+    b.add("count", this.count);
+    b.add("format", this.format);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    VariablesArguments other = (VariablesArguments) obj;
+    if (other.variablesReference != this.variablesReference)
+      return false;
+    if (this.filter == null) {
+      if (other.filter != null)
+        return false;
+    } else if (!this.filter.equals(other.filter))
+      return false;
+    if (this.start == null) {
+      if (other.start != null)
+        return false;
+    } else if (!this.start.equals(other.start))
+      return false;
+    if (this.count == null) {
+      if (other.count != null)
+        return false;
+    } else if (!this.count.equals(other.count))
+      return false;
+    if (this.format == null) {
+      if (other.format != null)
+        return false;
+    } else if (!this.format.equals(other.format))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + this.variablesReference;
+    result = prime * result + ((this.filter== null) ? 0 : this.filter.hashCode());
+    result = prime * result + ((this.start== null) ? 0 : this.start.hashCode());
+    result = prime * result + ((this.count== null) ? 0 : this.count.hashCode());
+    return prime * result + ((this.format== null) ? 0 : this.format.hashCode());
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/VariablesArgumentsFilter.java b/java/org/eclipse/lsp4j/debug/VariablesArgumentsFilter.java
new file mode 100644
index 0000000..00457b3
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/VariablesArgumentsFilter.java
@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+/**
+ * Optional filter to limit the child variables to either named or indexed. If omitted, both types are fetched.
+ */
+@SuppressWarnings("all")
+public enum VariablesArgumentsFilter {
+  INDEXED,
+  
+  NAMED;
+}
diff --git a/java/org/eclipse/lsp4j/debug/VariablesResponse.java b/java/org/eclipse/lsp4j/debug/VariablesResponse.java
new file mode 100644
index 0000000..704684b
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/VariablesResponse.java
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.debug;
+
+import java.util.Arrays;
+import org.eclipse.lsp4j.debug.Variable;
+import org.eclipse.lsp4j.debug.util.Preconditions;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+/**
+ * Response to 'variables' request.
+ */
+@SuppressWarnings("all")
+public class VariablesResponse {
+  /**
+   * All (or a range) of variables for the given variable reference.
+   */
+  @NonNull
+  private Variable[] variables;
+  
+  /**
+   * All (or a range) of variables for the given variable reference.
+   */
+  @Pure
+  @NonNull
+  public Variable[] getVariables() {
+    return this.variables;
+  }
+  
+  /**
+   * All (or a range) of variables for the given variable reference.
+   */
+  public void setVariables(@NonNull final Variable[] variables) {
+    this.variables = Preconditions.checkNotNull(variables, "variables");
+  }
+  
+  @Override
+  @Pure
+  public String toString() {
+    ToStringBuilder b = new ToStringBuilder(this);
+    b.add("variables", this.variables);
+    return b.toString();
+  }
+  
+  @Override
+  @Pure
+  public boolean equals(final Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    VariablesResponse other = (VariablesResponse) obj;
+    if (this.variables == null) {
+      if (other.variables != null)
+        return false;
+    } else if (!Arrays.deepEquals(this.variables, other.variables))
+      return false;
+    return true;
+  }
+  
+  @Override
+  @Pure
+  public int hashCode() {
+    return 31 * 1 + ((this.variables== null) ? 0 : Arrays.deepHashCode(this.variables));
+  }
+}
diff --git a/java/org/eclipse/lsp4j/debug/launch/DSPLauncher.java b/java/org/eclipse/lsp4j/debug/launch/DSPLauncher.java
new file mode 100644
index 0000000..191213d
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/launch/DSPLauncher.java
@@ -0,0 +1,118 @@
+/******************************************************************************
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.debug.launch;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.concurrent.ExecutorService;
+import java.util.function.Function;
+
+import org.eclipse.lsp4j.debug.services.IDebugProtocolClient;
+import org.eclipse.lsp4j.debug.services.IDebugProtocolServer;
+import org.eclipse.lsp4j.jsonrpc.Launcher;
+import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
+import org.eclipse.lsp4j.jsonrpc.debug.DebugLauncher;
+import org.eclipse.lsp4j.jsonrpc.validation.ReflectiveMessageValidator;
+
+/**
+ * Specialized launcher for the debug protocol.
+ */
+public final class DSPLauncher {
+	
+	private DSPLauncher() {}
+
+	/**
+	 * Create a new Launcher for a debug server and an input and output stream.
+	 * 
+	 * @param server - the server that receives method calls from the remote client
+	 * @param in - input stream to listen for incoming messages
+	 * @param out - output stream to send outgoing messages
+	 */
+	public static Launcher<IDebugProtocolClient> createServerLauncher(IDebugProtocolServer server, InputStream in,
+			OutputStream out) {
+		return DebugLauncher.createLauncher(server, IDebugProtocolClient.class, in, out);
+	}
+
+	/**
+	 * Create a new Launcher for a debug server and an input and output stream, and set up message validation and tracing.
+	 * 
+	 * @param server - the server that receives method calls from the remote client
+	 * @param in - input stream to listen for incoming messages
+	 * @param out - output stream to send outgoing messages
+	 * @param validate - whether messages should be validated with the {@link ReflectiveMessageValidator}
+	 * @param trace - a writer to which incoming and outgoing messages are traced, or {@code null} to disable tracing
+	 */
+	public static Launcher<IDebugProtocolClient> createServerLauncher(IDebugProtocolServer server, InputStream in,
+			OutputStream out, boolean validate, PrintWriter trace) {
+		return DebugLauncher.createLauncher(server, IDebugProtocolClient.class, in, out, validate, trace);
+	}
+
+	/**
+	 * Create a new Launcher for a debug server and an input and output stream. Threads are started with the given
+	 * executor service. The wrapper function is applied to the incoming and outgoing message streams so additional
+	 * message handling such as validation and tracing can be included.
+	 * 
+	 * @param server - the server that receives method calls from the remote client
+	 * @param in - input stream to listen for incoming messages
+	 * @param out - output stream to send outgoing messages
+	 * @param executorService - the executor service used to start threads
+	 * @param wrapper - a function for plugging in additional message consumers
+	 */
+	public static Launcher<IDebugProtocolClient> createServerLauncher(IDebugProtocolServer server, InputStream in,
+			OutputStream out, ExecutorService executorService, Function<MessageConsumer, MessageConsumer> wrapper) {
+		return DebugLauncher.createLauncher(server, IDebugProtocolClient.class, in, out, executorService, wrapper);
+	}
+
+	/**
+	 * Create a new Launcher for a debug client and an input and output stream.
+	 * 
+	 * @param client - the client that receives method calls from the remote server
+	 * @param in - input stream to listen for incoming messages
+	 * @param out - output stream to send outgoing messages
+	 */
+	public static Launcher<IDebugProtocolServer> createClientLauncher(IDebugProtocolClient client, InputStream in,
+			OutputStream out) {
+		return DebugLauncher.createLauncher(client, IDebugProtocolServer.class, in, out);
+	}
+
+	/**
+	 * Create a new Launcher for a debug client and an input and output stream, and set up message validation and tracing.
+	 * 
+	 * @param client - the client that receives method calls from the remote server
+	 * @param in - input stream to listen for incoming messages
+	 * @param out - output stream to send outgoing messages
+	 * @param validate - whether messages should be validated with the {@link ReflectiveMessageValidator}
+	 * @param trace - a writer to which incoming and outgoing messages are traced, or {@code null} to disable tracing
+	 */
+	public static Launcher<IDebugProtocolServer> createClientLauncher(IDebugProtocolClient client, InputStream in,
+			OutputStream out, boolean validate, PrintWriter trace) {
+		return DebugLauncher.createLauncher(client, IDebugProtocolServer.class, in, out, validate, trace);
+	}
+
+	/**
+	 * Create a new Launcher for a debug client and an input and output stream. Threads are started with the given
+	 * executor service. The wrapper function is applied to the incoming and outgoing message streams so additional
+	 * message handling such as validation and tracing can be included.
+	 * 
+	 * @param client - the client that receives method calls from the remote server
+	 * @param in - input stream to listen for incoming messages
+	 * @param out - output stream to send outgoing messages
+	 * @param executorService - the executor service used to start threads
+	 * @param wrapper - a function for plugging in additional message consumers
+	 */
+	public static Launcher<IDebugProtocolServer> createClientLauncher(IDebugProtocolClient client, InputStream in,
+			OutputStream out, ExecutorService executorService, Function<MessageConsumer, MessageConsumer> wrapper) {
+		return DebugLauncher.createLauncher(client, IDebugProtocolServer.class, in, out, executorService, wrapper);
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/debug/services/IDebugProtocolClient.java b/java/org/eclipse/lsp4j/debug/services/IDebugProtocolClient.java
new file mode 100644
index 0000000..7f44103
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/services/IDebugProtocolClient.java
@@ -0,0 +1,227 @@
+/******************************************************************************
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+
+package org.eclipse.lsp4j.debug.services;
+
+import org.eclipse.lsp4j.debug.BreakpointEventArguments;
+import org.eclipse.lsp4j.debug.CapabilitiesEventArguments;
+import org.eclipse.lsp4j.debug.ContinuedEventArguments;
+import org.eclipse.lsp4j.debug.ExitedEventArguments;
+import org.eclipse.lsp4j.debug.InvalidatedEventArguments;
+import org.eclipse.lsp4j.debug.LoadedSourceEventArguments;
+import org.eclipse.lsp4j.debug.ModuleEventArguments;
+import org.eclipse.lsp4j.debug.OutputEventArguments;
+import org.eclipse.lsp4j.debug.ProcessEventArguments;
+import org.eclipse.lsp4j.debug.ProgressEndEventArguments;
+import org.eclipse.lsp4j.debug.ProgressStartEventArguments;
+import org.eclipse.lsp4j.debug.ProgressUpdateEventArguments;
+import org.eclipse.lsp4j.debug.StoppedEventArguments;
+import org.eclipse.lsp4j.debug.TerminatedEventArguments;
+import org.eclipse.lsp4j.debug.ThreadEventArguments;
+import org.eclipse.lsp4j.jsonrpc.services.JsonNotification;
+
+/**
+ * Declaration of client notifications for the
+ * <a href="https://microsoft.github.io/debug-adapter-protocol/">Debug Adapter
+ * Protocol</a>
+ */
+public interface IDebugProtocolClient {
+	/**
+	 * Version of Debug Protocol
+	 */
+	public static final String SCHEMA_VERSION = "1.42.0";
+
+	/**
+	 * This event indicates that the debug adapter is ready to accept configuration
+	 * requests (e.g. SetBreakpointsRequest, SetExceptionBreakpointsRequest).
+	 * <p>
+	 * A debug adapter is expected to send this event when it is ready to accept
+	 * configuration requests (but not before the 'initialize' request has
+	 * finished).
+	 * <p>
+	 * The sequence of events/requests is as follows:
+	 * <ul>
+	 * <li>adapters sends 'initialized' event (after the 'initialize' request has
+	 * returned)</li>
+	 * <li>frontend sends zero or more 'setBreakpoints' requests</li>
+	 * <li>frontend sends one 'setFunctionBreakpoints' request (if capability
+	 * 'supportsFunctionBreakpoints' is true)</li>
+	 * <li>frontend sends a 'setExceptionBreakpoints' request if one or more
+	 * 'exceptionBreakpointFilters' have been defined (or if
+	 * 'supportsConfigurationDoneRequest' is not defined or false)</li>
+	 * <li>frontend sends other future configuration requests</li>
+	 * <li>frontend sends one 'configurationDone' request to indicate the end of the
+	 * configuration.</li>
+	 * </ul>
+	 */
+	@JsonNotification
+	default void initialized() {
+	}
+
+	/**
+	 * The event indicates that the execution of the debuggee has stopped due to
+	 * some condition.
+	 * <p>
+	 * This can be caused by a break point previously set, a stepping request has
+	 * completed, by executing a debugger statement etc.
+	 */
+	@JsonNotification
+	default void stopped(StoppedEventArguments args) {
+	}
+
+	/**
+	 * The event indicates that the execution of the debuggee has continued.
+	 * <p>
+	 * Please note: a debug adapter is not expected to send this event in response
+	 * to a request that implies that execution continues, e.g. 'launch' or
+	 * 'continue'.
+	 * <p>
+	 * It is only necessary to send a 'continued' event if there was no previous
+	 * request that implied this.
+	 */
+	@JsonNotification
+	default void continued(ContinuedEventArguments args) {
+	}
+
+	/**
+	 * The event indicates that the debuggee has exited and returns its exit code.
+	 */
+	@JsonNotification
+	default void exited(ExitedEventArguments args) {
+	}
+
+	/**
+	 * The event indicates that debugging of the debuggee has terminated. This does
+	 * **not** mean that the debuggee itself has exited.
+	 */
+	@JsonNotification
+	default void terminated(TerminatedEventArguments args) {
+	}
+
+	/**
+	 * The event indicates that a thread has started or exited.
+	 */
+	@JsonNotification
+	default void thread(ThreadEventArguments args) {
+	}
+
+	/**
+	 * The event indicates that the target has produced some output.
+	 */
+	@JsonNotification
+	default void output(OutputEventArguments args) {
+	}
+
+	/**
+	 * The event indicates that some information about a breakpoint has changed.
+	 */
+	@JsonNotification
+	default void breakpoint(BreakpointEventArguments args) {
+	}
+
+	/**
+	 * The event indicates that some information about a module has changed.
+	 */
+	@JsonNotification
+	default void module(ModuleEventArguments args) {
+	}
+
+	/**
+	 * The event indicates that some source has been added, changed, or removed from
+	 * the set of all loaded sources.
+	 */
+	@JsonNotification
+	default void loadedSource(LoadedSourceEventArguments args) {
+	}
+
+	/**
+	 * The event indicates that the debugger has begun debugging a new process.
+	 * Either one that it has launched, or one that it has attached to.
+	 */
+	@JsonNotification
+	default void process(ProcessEventArguments args) {
+	}
+
+	/**
+	 * The event indicates that one or more capabilities have changed.
+	 * <p>
+	 * Since the capabilities are dependent on the frontend and its UI, it might not
+	 * be possible to change that at random times (or too late).
+	 * <p>
+	 * Consequently this event has a hint characteristic: a frontend can only be
+	 * expected to make a 'best effort' in honouring individual capabilities but
+	 * there are no guarantees.
+	 * <p>
+	 * Only changed capabilities need to be included, all other capabilities keep
+	 * their values.
+	 */
+	@JsonNotification
+	default void capabilities(CapabilitiesEventArguments args) {
+	}
+
+	/**
+	 * The event signals that a long running operation is about to start and
+	 * <p>
+	 * provides additional information for the client to set up a corresponding
+	 * progress and cancellation UI.
+	 * <p>
+	 * The client is free to delay the showing of the UI in order to reduce flicker.
+	 * <p>
+	 * This event should only be sent if the client has passed the value true for
+	 * the 'supportsProgressReporting' capability of the 'initialize' request.
+	 */
+	@JsonNotification
+	default void progressStart(ProgressStartEventArguments args) {
+	}
+
+	/**
+	 * The event signals that the progress reporting needs to updated with a new
+	 * message and/or percentage.
+	 * <p>
+	 * The client does not have to update the UI immediately, but the clients needs
+	 * to keep track of the message and/or percentage values.
+	 * <p>
+	 * This event should only be sent if the client has passed the value true for
+	 * the 'supportsProgressReporting' capability of the 'initialize' request.
+	 */
+	@JsonNotification
+	default void progressUpdate(ProgressUpdateEventArguments args) {
+	}
+
+	/**
+	 * The event signals the end of the progress reporting with an optional final
+	 * message.
+	 * <p>
+	 * This event should only be sent if the client has passed the value true for
+	 * the 'supportsProgressReporting' capability of the 'initialize' request.
+	 */
+	@JsonNotification
+	default void progressEnd(ProgressEndEventArguments args) {
+	}
+
+	/**
+	 * This event signals that some state in the debug adapter has changed and
+	 * requires that the client needs to re-render the data snapshot previously
+	 * requested.
+	 * <p>
+	 * Debug adapters do not have to emit this event for runtime changes like
+	 * stopped or thread events because in that case the client refetches the new
+	 * state anyway. But the event can be used for example to refresh the UI after
+	 * rendering formatting has changed in the debug adapter.
+	 * <p>
+	 * This event should only be sent if the debug adapter has received a value true
+	 * for the 'supportsInvalidatedEvent' capability of the 'initialize' request.
+	 */
+	@JsonNotification
+	default void invalidated(InvalidatedEventArguments args) {
+	}
+}
diff --git a/java/org/eclipse/lsp4j/debug/services/IDebugProtocolServer.java b/java/org/eclipse/lsp4j/debug/services/IDebugProtocolServer.java
new file mode 100644
index 0000000..d5b33ee
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/services/IDebugProtocolServer.java
@@ -0,0 +1,680 @@
+/******************************************************************************
+ * Copyright (c) 2017, 2020 Kichwa Coders Ltd. and others.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+
+package org.eclipse.lsp4j.debug.services;
+
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+
+import org.eclipse.lsp4j.debug.BreakpointLocationsArguments;
+import org.eclipse.lsp4j.debug.BreakpointLocationsResponse;
+import org.eclipse.lsp4j.debug.CancelArguments;
+import org.eclipse.lsp4j.debug.Capabilities;
+import org.eclipse.lsp4j.debug.CompletionsArguments;
+import org.eclipse.lsp4j.debug.CompletionsResponse;
+import org.eclipse.lsp4j.debug.ConfigurationDoneArguments;
+import org.eclipse.lsp4j.debug.ContinueArguments;
+import org.eclipse.lsp4j.debug.ContinueResponse;
+import org.eclipse.lsp4j.debug.DataBreakpointInfoArguments;
+import org.eclipse.lsp4j.debug.DataBreakpointInfoResponse;
+import org.eclipse.lsp4j.debug.DisassembleArguments;
+import org.eclipse.lsp4j.debug.DisassembleResponse;
+import org.eclipse.lsp4j.debug.DisconnectArguments;
+import org.eclipse.lsp4j.debug.EvaluateArguments;
+import org.eclipse.lsp4j.debug.EvaluateResponse;
+import org.eclipse.lsp4j.debug.ExceptionInfoArguments;
+import org.eclipse.lsp4j.debug.ExceptionInfoResponse;
+import org.eclipse.lsp4j.debug.GotoArguments;
+import org.eclipse.lsp4j.debug.GotoTargetsArguments;
+import org.eclipse.lsp4j.debug.GotoTargetsResponse;
+import org.eclipse.lsp4j.debug.InitializeRequestArguments;
+import org.eclipse.lsp4j.debug.LoadedSourcesArguments;
+import org.eclipse.lsp4j.debug.LoadedSourcesResponse;
+import org.eclipse.lsp4j.debug.ModulesArguments;
+import org.eclipse.lsp4j.debug.ModulesResponse;
+import org.eclipse.lsp4j.debug.NextArguments;
+import org.eclipse.lsp4j.debug.PauseArguments;
+import org.eclipse.lsp4j.debug.ReadMemoryArguments;
+import org.eclipse.lsp4j.debug.ReadMemoryResponse;
+import org.eclipse.lsp4j.debug.RestartArguments;
+import org.eclipse.lsp4j.debug.RestartFrameArguments;
+import org.eclipse.lsp4j.debug.ReverseContinueArguments;
+import org.eclipse.lsp4j.debug.RunInTerminalRequestArguments;
+import org.eclipse.lsp4j.debug.RunInTerminalResponse;
+import org.eclipse.lsp4j.debug.ScopesArguments;
+import org.eclipse.lsp4j.debug.ScopesResponse;
+import org.eclipse.lsp4j.debug.SetBreakpointsArguments;
+import org.eclipse.lsp4j.debug.SetBreakpointsResponse;
+import org.eclipse.lsp4j.debug.SetDataBreakpointsArguments;
+import org.eclipse.lsp4j.debug.SetDataBreakpointsResponse;
+import org.eclipse.lsp4j.debug.SetExceptionBreakpointsArguments;
+import org.eclipse.lsp4j.debug.SetExpressionArguments;
+import org.eclipse.lsp4j.debug.SetExpressionResponse;
+import org.eclipse.lsp4j.debug.SetFunctionBreakpointsArguments;
+import org.eclipse.lsp4j.debug.SetFunctionBreakpointsResponse;
+import org.eclipse.lsp4j.debug.SetInstructionBreakpointsArguments;
+import org.eclipse.lsp4j.debug.SetInstructionBreakpointsResponse;
+import org.eclipse.lsp4j.debug.SetVariableArguments;
+import org.eclipse.lsp4j.debug.SetVariableResponse;
+import org.eclipse.lsp4j.debug.SourceArguments;
+import org.eclipse.lsp4j.debug.SourceResponse;
+import org.eclipse.lsp4j.debug.StackTraceArguments;
+import org.eclipse.lsp4j.debug.StackTraceResponse;
+import org.eclipse.lsp4j.debug.StepBackArguments;
+import org.eclipse.lsp4j.debug.StepInArguments;
+import org.eclipse.lsp4j.debug.StepInTargetsArguments;
+import org.eclipse.lsp4j.debug.StepInTargetsResponse;
+import org.eclipse.lsp4j.debug.StepOutArguments;
+import org.eclipse.lsp4j.debug.TerminateArguments;
+import org.eclipse.lsp4j.debug.TerminateThreadsArguments;
+import org.eclipse.lsp4j.debug.ThreadsResponse;
+import org.eclipse.lsp4j.debug.VariablesArguments;
+import org.eclipse.lsp4j.debug.VariablesResponse;
+import org.eclipse.lsp4j.jsonrpc.services.JsonRequest;
+
+/**
+ * Declaration of server requests for the
+ * <a href="https://microsoft.github.io/debug-adapter-protocol/">Debug Adapter
+ * Protocol</a>
+ */
+public interface IDebugProtocolServer {
+	/**
+	 * Version of Debug Protocol
+	 */
+	public static final String SCHEMA_VERSION = "1.42.0";
+
+	/**
+	 * The 'cancel' request is used by the frontend in two situations:
+	 * <ul>
+	 * <li>to indicate that it is no longer interested in the result produced by a
+	 * specific request issued earlier</li>
+	 * <li>to cancel a progress sequence. Clients should only call this request if
+	 * the capability 'supportsCancelRequest' is true.</li>
+	 * </ul>
+	 * <p>
+	 * This request has a hint characteristic: a debug adapter can only be expected
+	 * to make a 'best effort' in honouring this request but there are no
+	 * guarantees.
+	 * <p>
+	 * The 'cancel' request may return an error if it could not cancel an operation
+	 * but a frontend should refrain from presenting this error to end users.
+	 * <p>
+	 * A frontend client should only call this request if the capability
+	 * 'supportsCancelRequest' is true.
+	 * <p>
+	 * The request that got canceled still needs to send a response back. This can
+	 * either be a normal result ('success' attribute true)
+	 * <p>
+	 * or an error response ('success' attribute false and the 'message' set to
+	 * 'cancelled').
+	 * <p>
+	 * Returning partial results from a cancelled request is possible but please
+	 * note that a frontend client has no generic way for detecting that a response
+	 * is partial or not.
+	 * <p>
+	 * The progress that got cancelled still needs to send a 'progressEnd' event
+	 * back.
+	 * <p>
+	 * A client should not assume that progress just got cancelled after sending the
+	 * 'cancel' request.
+	 */
+	@JsonRequest
+	default CompletableFuture<Void> cancel(CancelArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * This optional request is sent from the debug adapter to the client to run a
+	 * command in a terminal.
+	 * <p>
+	 * This is typically used to launch the debuggee in a terminal provided by the
+	 * client.
+	 * <p>
+	 * This request should only be called if the client has passed the value true
+	 * for the 'supportsRunInTerminalRequest' capability of the 'initialize'
+	 * request.
+	 */
+	@JsonRequest
+	default CompletableFuture<RunInTerminalResponse> runInTerminal(RunInTerminalRequestArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The 'initialize' request is sent as the first request from the client to the
+	 * debug adapter
+	 * <p>
+	 * in order to configure it with client capabilities and to retrieve
+	 * capabilities from the debug adapter.
+	 * <p>
+	 * Until the debug adapter has responded to with an 'initialize' response, the
+	 * client must not send any additional requests or events to the debug adapter.
+	 * <p>
+	 * In addition the debug adapter is not allowed to send any requests or events
+	 * to the client until it has responded with an 'initialize' response.
+	 * <p>
+	 * The 'initialize' request may only be sent once.
+	 */
+	@JsonRequest
+	default CompletableFuture<Capabilities> initialize(InitializeRequestArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * This optional request indicates that the client has finished initialization
+	 * of the debug adapter.
+	 * <p>
+	 * So it is the last request in the sequence of configuration requests (which
+	 * was started by the 'initialized' event).
+	 * <p>
+	 * Clients should only call this request if the capability
+	 * 'supportsConfigurationDoneRequest' is true.
+	 */
+	@JsonRequest
+	default CompletableFuture<Void> configurationDone(ConfigurationDoneArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * This launch request is sent from the client to the debug adapter to start the
+	 * debuggee with or without debugging (if 'noDebug' is true).
+	 * <p>
+	 * Since launching is debugger/runtime specific, the arguments for this request
+	 * are not part of this specification.
+	 */
+	@JsonRequest
+	default CompletableFuture<Void> launch(Map<String, Object> args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The attach request is sent from the client to the debug adapter to attach to
+	 * a debuggee that is already running.
+	 * <p>
+	 * Since attaching is debugger/runtime specific, the arguments for this request
+	 * are not part of this specification.
+	 */
+	@JsonRequest
+	default CompletableFuture<Void> attach(Map<String, Object> args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Restarts a debug session. Clients should only call this request if the
+	 * capability 'supportsRestartRequest' is true.
+	 * <p>
+	 * If the capability is missing or has the value false, a typical client will
+	 * emulate 'restart' by terminating the debug adapter first and then launching
+	 * it anew.
+	 */
+	@JsonRequest
+	default CompletableFuture<Void> restart(RestartArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The 'disconnect' request is sent from the client to the debug adapter in
+	 * order to stop debugging.
+	 * <p>
+	 * It asks the debug adapter to disconnect from the debuggee and to terminate
+	 * the debug adapter.
+	 * <p>
+	 * If the debuggee has been started with the 'launch' request, the 'disconnect'
+	 * request terminates the debuggee.
+	 * <p>
+	 * If the 'attach' request was used to connect to the debuggee, 'disconnect'
+	 * does not terminate the debuggee.
+	 * <p>
+	 * This behavior can be controlled with the 'terminateDebuggee' argument (if
+	 * supported by the debug adapter).
+	 */
+	@JsonRequest
+	default CompletableFuture<Void> disconnect(DisconnectArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The 'terminate' request is sent from the client to the debug adapter in order
+	 * to give the debuggee a chance for terminating itself.
+	 * <p>
+	 * Clients should only call this request if the capability
+	 * 'supportsTerminateRequest' is true.
+	 */
+	@JsonRequest
+	default CompletableFuture<Void> terminate(TerminateArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The 'breakpointLocations' request returns all possible locations for source
+	 * breakpoints in a given range.
+	 * <p>
+	 * Clients should only call this request if the capability
+	 * 'supportsBreakpointLocationsRequest' is true.
+	 */
+	@JsonRequest
+	default CompletableFuture<BreakpointLocationsResponse> breakpointLocations(BreakpointLocationsArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Sets multiple breakpoints for a single source and clears all previous
+	 * breakpoints in that source.
+	 * <p>
+	 * To clear all breakpoint for a source, specify an empty array.
+	 * <p>
+	 * When a breakpoint is hit, a 'stopped' event (with reason 'breakpoint') is
+	 * generated.
+	 */
+	@JsonRequest
+	default CompletableFuture<SetBreakpointsResponse> setBreakpoints(SetBreakpointsArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Replaces all existing function breakpoints with new function breakpoints.
+	 * <p>
+	 * To clear all function breakpoints, specify an empty array.
+	 * <p>
+	 * When a function breakpoint is hit, a 'stopped' event (with reason 'function
+	 * breakpoint') is generated.
+	 * <p>
+	 * Clients should only call this request if the capability
+	 * 'supportsFunctionBreakpoints' is true.
+	 */
+	@JsonRequest
+	default CompletableFuture<SetFunctionBreakpointsResponse> setFunctionBreakpoints(
+			SetFunctionBreakpointsArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The request configures the debuggers response to thrown exceptions.
+	 * <p>
+	 * If an exception is configured to break, a 'stopped' event is fired (with
+	 * reason 'exception').
+	 * <p>
+	 * Clients should only call this request if the capability
+	 * 'exceptionBreakpointFilters' returns one or more filters.
+	 */
+	@JsonRequest
+	default CompletableFuture<Void> setExceptionBreakpoints(SetExceptionBreakpointsArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Obtains information on a possible data breakpoint that could be set on an
+	 * expression or variable.
+	 * <p>
+	 * Clients should only call this request if the capability
+	 * 'supportsDataBreakpoints' is true.
+	 */
+	@JsonRequest
+	default CompletableFuture<DataBreakpointInfoResponse> dataBreakpointInfo(DataBreakpointInfoArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Replaces all existing data breakpoints with new data breakpoints.
+	 * <p>
+	 * To clear all data breakpoints, specify an empty array.
+	 * <p>
+	 * When a data breakpoint is hit, a 'stopped' event (with reason 'data
+	 * breakpoint') is generated.
+	 * <p>
+	 * Clients should only call this request if the capability
+	 * 'supportsDataBreakpoints' is true.
+	 */
+	@JsonRequest
+	default CompletableFuture<SetDataBreakpointsResponse> setDataBreakpoints(SetDataBreakpointsArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Replaces all existing instruction breakpoints. Typically, instruction
+	 * breakpoints would be set from a diassembly window.
+	 * <p>
+	 * To clear all instruction breakpoints, specify an empty array.
+	 * <p>
+	 * When an instruction breakpoint is hit, a 'stopped' event (with reason
+	 * 'instruction breakpoint') is generated.
+	 * <p>
+	 * Clients should only call this request if the capability
+	 * 'supportsInstructionBreakpoints' is true.
+	 */
+	@JsonRequest
+	default CompletableFuture<SetInstructionBreakpointsResponse> setInstructionBreakpoints(
+			SetInstructionBreakpointsArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The request starts the debuggee to run again.
+	 */
+	@JsonRequest(value = "continue")
+	default CompletableFuture<ContinueResponse> continue_(ContinueArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The request starts the debuggee to run again for one step.
+	 * <p>
+	 * The debug adapter first sends the response and then a 'stopped' event (with
+	 * reason 'step') after the step has completed.
+	 */
+	@JsonRequest
+	default CompletableFuture<Void> next(NextArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The request starts the debuggee to step into a function/method if possible.
+	 * <p>
+	 * If it cannot step into a target, 'stepIn' behaves like 'next'.
+	 * <p>
+	 * The debug adapter first sends the response and then a 'stopped' event (with
+	 * reason 'step') after the step has completed.
+	 * <p>
+	 * If there are multiple function/method calls (or other targets) on the source
+	 * line,
+	 * <p>
+	 * the optional argument 'targetId' can be used to control into which target the
+	 * 'stepIn' should occur.
+	 * <p>
+	 * The list of possible targets for a given source line can be retrieved via the
+	 * 'stepInTargets' request.
+	 */
+	@JsonRequest
+	default CompletableFuture<Void> stepIn(StepInArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The request starts the debuggee to run again for one step.
+	 * <p>
+	 * The debug adapter first sends the response and then a 'stopped' event (with
+	 * reason 'step') after the step has completed.
+	 */
+	@JsonRequest
+	default CompletableFuture<Void> stepOut(StepOutArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The request starts the debuggee to run one step backwards.
+	 * <p>
+	 * The debug adapter first sends the response and then a 'stopped' event (with
+	 * reason 'step') after the step has completed.
+	 * <p>
+	 * Clients should only call this request if the capability 'supportsStepBack' is
+	 * true.
+	 */
+	@JsonRequest
+	default CompletableFuture<Void> stepBack(StepBackArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The request starts the debuggee to run backward.
+	 * <p>
+	 * Clients should only call this request if the capability 'supportsStepBack' is
+	 * true.
+	 */
+	@JsonRequest
+	default CompletableFuture<Void> reverseContinue(ReverseContinueArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The request restarts execution of the specified stackframe.
+	 * <p>
+	 * The debug adapter first sends the response and then a 'stopped' event (with
+	 * reason 'restart') after the restart has completed.
+	 * <p>
+	 * Clients should only call this request if the capability
+	 * 'supportsRestartFrame' is true.
+	 */
+	@JsonRequest
+	default CompletableFuture<Void> restartFrame(RestartFrameArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The request sets the location where the debuggee will continue to run.
+	 * <p>
+	 * This makes it possible to skip the execution of code or to executed code
+	 * again.
+	 * <p>
+	 * The code between the current location and the goto target is not executed but
+	 * skipped.
+	 * <p>
+	 * The debug adapter first sends the response and then a 'stopped' event with
+	 * reason 'goto'.
+	 * <p>
+	 * Clients should only call this request if the capability
+	 * 'supportsGotoTargetsRequest' is true (because only then goto targets exist
+	 * that can be passed as arguments).
+	 */
+	@JsonRequest(value = "goto")
+	default CompletableFuture<Void> goto_(GotoArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The request suspends the debuggee.
+	 * <p>
+	 * The debug adapter first sends the response and then a 'stopped' event (with
+	 * reason 'pause') after the thread has been paused successfully.
+	 */
+	@JsonRequest
+	default CompletableFuture<Void> pause(PauseArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The request returns a stacktrace from the current execution state of a given
+	 * thread.
+	 * <p>
+	 * A client can request all stack frames by omitting the startFrame and levels
+	 * arguments. For performance conscious clients and if the debug adapter's
+	 * 'supportsDelayedStackTraceLoading' capability is true, stack frames can be
+	 * retrieved in a piecemeal way with the startFrame and levels arguments. The
+	 * response of the stackTrace request may contain a totalFrames property that
+	 * hints at the total number of frames in the stack. If a client needs this
+	 * total number upfront, it can issue a request for a single (first) frame and
+	 * depending on the value of totalFrames decide how to proceed. In any case a
+	 * client should be prepared to receive less frames than requested, which is an
+	 * indication that the end of the stack has been reached.
+	 */
+	@JsonRequest
+	default CompletableFuture<StackTraceResponse> stackTrace(StackTraceArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The request returns the variable scopes for a given stackframe ID.
+	 */
+	@JsonRequest
+	default CompletableFuture<ScopesResponse> scopes(ScopesArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Retrieves all child variables for the given variable reference.
+	 * <p>
+	 * An optional filter can be used to limit the fetched children to either named
+	 * or indexed children.
+	 */
+	@JsonRequest
+	default CompletableFuture<VariablesResponse> variables(VariablesArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Set the variable with the given name in the variable container to a new
+	 * value. Clients should only call this request if the capability
+	 * 'supportsSetVariable' is true.
+	 */
+	@JsonRequest
+	default CompletableFuture<SetVariableResponse> setVariable(SetVariableArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The request retrieves the source code for a given source reference.
+	 */
+	@JsonRequest
+	default CompletableFuture<SourceResponse> source(SourceArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The request retrieves a list of all threads.
+	 */
+	@JsonRequest
+	default CompletableFuture<ThreadsResponse> threads() {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The request terminates the threads with the given ids.
+	 * <p>
+	 * Clients should only call this request if the capability
+	 * 'supportsTerminateThreadsRequest' is true.
+	 */
+	@JsonRequest
+	default CompletableFuture<Void> terminateThreads(TerminateThreadsArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Modules can be retrieved from the debug adapter with this request which can
+	 * either return all modules or a range of modules to support paging.
+	 * <p>
+	 * Clients should only call this request if the capability
+	 * 'supportsModulesRequest' is true.
+	 */
+	@JsonRequest
+	default CompletableFuture<ModulesResponse> modules(ModulesArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Retrieves the set of all sources currently loaded by the debugged process.
+	 * <p>
+	 * Clients should only call this request if the capability
+	 * 'supportsLoadedSourcesRequest' is true.
+	 */
+	@JsonRequest
+	default CompletableFuture<LoadedSourcesResponse> loadedSources(LoadedSourcesArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Evaluates the given expression in the context of the top most stack frame.
+	 * <p>
+	 * The expression has access to any variables and arguments that are in scope.
+	 */
+	@JsonRequest
+	default CompletableFuture<EvaluateResponse> evaluate(EvaluateArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Evaluates the given 'value' expression and assigns it to the 'expression'
+	 * which must be a modifiable l-value.
+	 * <p>
+	 * The expressions have access to any variables and arguments that are in scope
+	 * of the specified frame.
+	 * <p>
+	 * Clients should only call this request if the capability
+	 * 'supportsSetExpression' is true.
+	 */
+	@JsonRequest
+	default CompletableFuture<SetExpressionResponse> setExpression(SetExpressionArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * This request retrieves the possible stepIn targets for the specified stack
+	 * frame.
+	 * <p>
+	 * These targets can be used in the 'stepIn' request.
+	 * <p>
+	 * The StepInTargets may only be called if the 'supportsStepInTargetsRequest'
+	 * capability exists and is true.
+	 * <p>
+	 * Clients should only call this request if the capability
+	 * 'supportsStepInTargetsRequest' is true.
+	 */
+	@JsonRequest
+	default CompletableFuture<StepInTargetsResponse> stepInTargets(StepInTargetsArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * This request retrieves the possible goto targets for the specified source
+	 * location.
+	 * <p>
+	 * These targets can be used in the 'goto' request.
+	 * <p>
+	 * Clients should only call this request if the capability
+	 * 'supportsGotoTargetsRequest' is true.
+	 */
+	@JsonRequest
+	default CompletableFuture<GotoTargetsResponse> gotoTargets(GotoTargetsArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Returns a list of possible completions for a given caret position and text.
+	 * <p>
+	 * Clients should only call this request if the capability
+	 * 'supportsCompletionsRequest' is true.
+	 */
+	@JsonRequest
+	default CompletableFuture<CompletionsResponse> completions(CompletionsArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Retrieves the details of the exception that caused this event to be raised.
+	 * <p>
+	 * Clients should only call this request if the capability
+	 * 'supportsExceptionInfoRequest' is true.
+	 */
+	@JsonRequest
+	default CompletableFuture<ExceptionInfoResponse> exceptionInfo(ExceptionInfoArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Reads bytes from memory at the provided location.
+	 * <p>
+	 * Clients should only call this request if the capability
+	 * 'supportsReadMemoryRequest' is true.
+	 */
+	@JsonRequest
+	default CompletableFuture<ReadMemoryResponse> readMemory(ReadMemoryArguments args) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Disassembles code stored at the provided location.
+	 * <p>
+	 * Clients should only call this request if the capability
+	 * 'supportsDisassembleRequest' is true.
+	 */
+	@JsonRequest
+	default CompletableFuture<DisassembleResponse> disassemble(DisassembleArguments args) {
+		throw new UnsupportedOperationException();
+	}
+}
diff --git a/java/org/eclipse/lsp4j/debug/util/Preconditions.java b/java/org/eclipse/lsp4j/debug/util/Preconditions.java
new file mode 100644
index 0000000..6892a64
--- /dev/null
+++ b/java/org/eclipse/lsp4j/debug/util/Preconditions.java
@@ -0,0 +1,34 @@
+/******************************************************************************
+ * Copyright (c) 2019 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.debug.util;
+
+/**
+ * Utilities for checking method and constructor arguments.
+ */
+public final class Preconditions {
+	
+	private Preconditions() {}
+	
+	private static boolean nullChecks = true;
+	
+	public static void enableNullChecks(boolean enable) {
+		Preconditions.nullChecks = enable;
+	}
+	
+	public static <T> T checkNotNull(T object, String propertyName) {
+		if (nullChecks && object == null) {
+			throw new IllegalArgumentException("Property must not be null: " + propertyName);
+		}
+		return object;
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/generator/EitherTypeArgument.java b/java/org/eclipse/lsp4j/generator/EitherTypeArgument.java
new file mode 100644
index 0000000..f14a96e
--- /dev/null
+++ b/java/org/eclipse/lsp4j/generator/EitherTypeArgument.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.generator;
+
+import org.eclipse.xtend.lib.annotations.Accessors;
+import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor;
+import org.eclipse.xtend.lib.macro.declaration.TypeReference;
+import org.eclipse.xtext.xbase.lib.Pure;
+
+@Accessors
+@FinalFieldsConstructor
+@SuppressWarnings("all")
+public class EitherTypeArgument {
+  private final TypeReference type;
+  
+  private final EitherTypeArgument parent;
+  
+  private final boolean right;
+  
+  public EitherTypeArgument(final TypeReference type, final EitherTypeArgument parent, final boolean right) {
+    super();
+    this.type = type;
+    this.parent = parent;
+    this.right = right;
+  }
+  
+  @Pure
+  public TypeReference getType() {
+    return this.type;
+  }
+  
+  @Pure
+  public EitherTypeArgument getParent() {
+    return this.parent;
+  }
+  
+  @Pure
+  public boolean isRight() {
+    return this.right;
+  }
+}
diff --git a/java/org/eclipse/lsp4j/generator/JsonRpcData.java b/java/org/eclipse/lsp4j/generator/JsonRpcData.java
new file mode 100644
index 0000000..d087138
--- /dev/null
+++ b/java/org/eclipse/lsp4j/generator/JsonRpcData.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.generator;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import org.eclipse.lsp4j.generator.JsonRpcDataProcessor;
+import org.eclipse.xtend.lib.macro.Active;
+
+/**
+ * Generates getters and setters for all fields as well as {@code equals} and {@code hashCode} implementations.
+ * All JSON-RPC protocol classes that are written in Xtend should be annotated with this.
+ */
+@Target(ElementType.TYPE)
+@Active(JsonRpcDataProcessor.class)
+@Retention(RetentionPolicy.SOURCE)
+@SuppressWarnings("all")
+public @interface JsonRpcData {
+}
diff --git a/java/org/eclipse/lsp4j/generator/JsonRpcData.xtend b/java/org/eclipse/lsp4j/generator/JsonRpcData.xtend
new file mode 100644
index 0000000..7ee1f7c
--- /dev/null
+++ b/java/org/eclipse/lsp4j/generator/JsonRpcData.xtend
@@ -0,0 +1,28 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.generator
+
+import java.lang.annotation.ElementType
+import java.lang.annotation.Retention
+import java.lang.annotation.Target
+import org.eclipse.xtend.lib.macro.Active
+
+/**
+ * Generates getters and setters for all fields as well as {@code equals} and {@code hashCode} implementations.
+ * All JSON-RPC protocol classes that are written in Xtend should be annotated with this.
+ */
+@Target(ElementType.TYPE)
+@Active(JsonRpcDataProcessor)
+@Retention(SOURCE)
+annotation JsonRpcData {
+    
+}
\ No newline at end of file
diff --git a/java/org/eclipse/lsp4j/generator/JsonRpcDataProcessor.java b/java/org/eclipse/lsp4j/generator/JsonRpcDataProcessor.java
new file mode 100644
index 0000000..8b93e4f
--- /dev/null
+++ b/java/org/eclipse/lsp4j/generator/JsonRpcDataProcessor.java
@@ -0,0 +1,346 @@
+/**
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.generator;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.Iterables;
+import com.google.gson.annotations.JsonAdapter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.function.Consumer;
+import org.eclipse.lsp4j.generator.EitherTypeArgument;
+import org.eclipse.lsp4j.generator.JsonRpcData;
+import org.eclipse.lsp4j.generator.JsonRpcDataTransformationContext;
+import org.eclipse.lsp4j.generator.JsonType;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.xtend.lib.annotations.AccessorsProcessor;
+import org.eclipse.xtend.lib.annotations.EqualsHashCodeProcessor;
+import org.eclipse.xtend.lib.macro.AbstractClassProcessor;
+import org.eclipse.xtend.lib.macro.TransformationContext;
+import org.eclipse.xtend.lib.macro.declaration.AnnotationReference;
+import org.eclipse.xtend.lib.macro.declaration.AnnotationTypeDeclaration;
+import org.eclipse.xtend.lib.macro.declaration.ClassDeclaration;
+import org.eclipse.xtend.lib.macro.declaration.CompilationStrategy;
+import org.eclipse.xtend.lib.macro.declaration.FieldDeclaration;
+import org.eclipse.xtend.lib.macro.declaration.MutableClassDeclaration;
+import org.eclipse.xtend.lib.macro.declaration.MutableFieldDeclaration;
+import org.eclipse.xtend.lib.macro.declaration.MutableMethodDeclaration;
+import org.eclipse.xtend.lib.macro.declaration.MutableParameterDeclaration;
+import org.eclipse.xtend.lib.macro.declaration.Type;
+import org.eclipse.xtend.lib.macro.declaration.TypeDeclaration;
+import org.eclipse.xtend.lib.macro.declaration.TypeReference;
+import org.eclipse.xtend.lib.macro.declaration.Visibility;
+import org.eclipse.xtend2.lib.StringConcatenation;
+import org.eclipse.xtend2.lib.StringConcatenationClient;
+import org.eclipse.xtext.xbase.lib.CollectionLiterals;
+import org.eclipse.xtext.xbase.lib.Extension;
+import org.eclipse.xtext.xbase.lib.Functions.Function1;
+import org.eclipse.xtext.xbase.lib.IterableExtensions;
+import org.eclipse.xtext.xbase.lib.ObjectExtensions;
+import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
+import org.eclipse.xtext.xbase.lib.Pure;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+
+@SuppressWarnings("all")
+public class JsonRpcDataProcessor extends AbstractClassProcessor {
+  @Override
+  public void doTransform(final MutableClassDeclaration annotatedClass, final TransformationContext context) {
+    this.generateImpl(annotatedClass, context);
+  }
+  
+  protected MutableClassDeclaration generateImpl(final MutableClassDeclaration impl, @Extension final TransformationContext context) {
+    final Function1<AnnotationReference, Boolean> _function = (AnnotationReference it) -> {
+      AnnotationTypeDeclaration _annotationTypeDeclaration = it.getAnnotationTypeDeclaration();
+      Type _findTypeGlobally = context.findTypeGlobally(JsonRpcData.class);
+      return Boolean.valueOf(Objects.equal(_annotationTypeDeclaration, _findTypeGlobally));
+    };
+    impl.removeAnnotation(IterableExtensions.findFirst(impl.getAnnotations(), _function));
+    JsonRpcDataTransformationContext _jsonRpcDataTransformationContext = new JsonRpcDataTransformationContext(context);
+    this.generateImplMembers(impl, _jsonRpcDataTransformationContext);
+    this.generateToString(impl, context);
+    Type _type = impl.getExtendedClass().getType();
+    Type _type_1 = context.newTypeReference(Object.class).getType();
+    final boolean shouldIncludeSuper = (!Objects.equal(_type, _type_1));
+    final EqualsHashCodeProcessor.Util equalsHashCodeUtil = new EqualsHashCodeProcessor.Util(context);
+    final Function1<MutableFieldDeclaration, Boolean> _function_1 = (MutableFieldDeclaration it) -> {
+      boolean _isStatic = it.isStatic();
+      return Boolean.valueOf((!_isStatic));
+    };
+    final Iterable<? extends MutableFieldDeclaration> fields = IterableExtensions.filter(impl.getDeclaredFields(), _function_1);
+    equalsHashCodeUtil.addEquals(impl, fields, shouldIncludeSuper);
+    equalsHashCodeUtil.addHashCode(impl, fields, shouldIncludeSuper);
+    return impl;
+  }
+  
+  protected void generateImplMembers(final MutableClassDeclaration impl, @Extension final JsonRpcDataTransformationContext context) {
+    final Function1<MutableFieldDeclaration, Boolean> _function = (MutableFieldDeclaration it) -> {
+      boolean _isStatic = it.isStatic();
+      return Boolean.valueOf((!_isStatic));
+    };
+    final Consumer<MutableFieldDeclaration> _function_1 = (MutableFieldDeclaration field) -> {
+      final AccessorsProcessor.Util accessorsUtil = new AccessorsProcessor.Util(context);
+      final AnnotationReference deprecated = field.findAnnotation(context.findTypeGlobally(Deprecated.class));
+      accessorsUtil.addGetter(field, Visibility.PUBLIC);
+      AnnotationReference _findAnnotation = field.findAnnotation(context.newTypeReference(NonNull.class).getType());
+      final boolean hasNonNull = (_findAnnotation != null);
+      AnnotationReference _findAnnotation_1 = field.findAnnotation(context.newTypeReference(JsonAdapter.class).getType());
+      final boolean hasJsonAdapter = (_findAnnotation_1 != null);
+      MutableMethodDeclaration _findDeclaredMethod = impl.findDeclaredMethod(accessorsUtil.getGetterName(field));
+      final Procedure1<MutableMethodDeclaration> _function_2 = (MutableMethodDeclaration it) -> {
+        it.setDocComment(field.getDocComment());
+        if (hasNonNull) {
+          it.addAnnotation(context.newAnnotationReference(NonNull.class));
+        }
+        if ((deprecated != null)) {
+          it.addAnnotation(context.newAnnotationReference(Deprecated.class));
+        }
+      };
+      ObjectExtensions.<MutableMethodDeclaration>operator_doubleArrow(_findDeclaredMethod, _function_2);
+      boolean _isInferred = field.getType().isInferred();
+      boolean _not = (!_isInferred);
+      if (_not) {
+        accessorsUtil.addSetter(field, Visibility.PUBLIC);
+        final String setterName = accessorsUtil.getSetterName(field);
+        MutableMethodDeclaration _findDeclaredMethod_1 = impl.findDeclaredMethod(setterName, field.getType());
+        final Procedure1<MutableMethodDeclaration> _function_3 = (MutableMethodDeclaration it) -> {
+          it.setDocComment(field.getDocComment());
+          if (hasNonNull) {
+            final MutableParameterDeclaration parameter = IterableExtensions.head(it.getParameters());
+            parameter.addAnnotation(context.newAnnotationReference(NonNull.class));
+            StringConcatenationClient _client = new StringConcatenationClient() {
+              @Override
+              protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
+                _builder.append("this.");
+                String _simpleName = field.getSimpleName();
+                _builder.append(_simpleName);
+                _builder.append(" = ");
+                TypeReference _preconditionsUtil = JsonRpcDataProcessor.this.getPreconditionsUtil(impl, context);
+                _builder.append(_preconditionsUtil);
+                _builder.append(".checkNotNull(");
+                String _simpleName_1 = parameter.getSimpleName();
+                _builder.append(_simpleName_1);
+                _builder.append(", \"");
+                String _simpleName_2 = field.getSimpleName();
+                _builder.append(_simpleName_2);
+                _builder.append("\");");
+                _builder.newLineIfNotEmpty();
+              }
+            };
+            it.setBody(_client);
+          }
+          if ((deprecated != null)) {
+            it.addAnnotation(context.newAnnotationReference(Deprecated.class));
+          }
+        };
+        ObjectExtensions.<MutableMethodDeclaration>operator_doubleArrow(_findDeclaredMethod_1, _function_3);
+        final Collection<EitherTypeArgument> childTypes = context.getChildTypes(field.getType());
+        boolean _isEmpty = childTypes.isEmpty();
+        boolean _not_1 = (!_isEmpty);
+        if (_not_1) {
+          final Function1<EitherTypeArgument, JsonType> _function_4 = (EitherTypeArgument it) -> {
+            return context.getJsonType(it.getType());
+          };
+          final List<JsonType> jsonTypes = IterableExtensions.<JsonType>toList(IterableExtensions.<EitherTypeArgument, JsonType>map(childTypes, _function_4));
+          int _size = jsonTypes.size();
+          int _size_1 = IterableExtensions.<JsonType>toSet(jsonTypes).size();
+          boolean _tripleNotEquals = (_size != _size_1);
+          if (_tripleNotEquals) {
+            if ((!hasJsonAdapter)) {
+              StringConcatenation _builder = new StringConcatenation();
+              _builder.append("The json types of an Either must be distinct.");
+              context.addWarning(field, _builder.toString());
+            }
+          } else {
+            for (final EitherTypeArgument childType : childTypes) {
+              this.addEitherSetter(field, setterName, childType, context);
+            }
+          }
+        }
+      }
+    };
+    IterableExtensions.filter(impl.getDeclaredFields(), _function).forEach(_function_1);
+  }
+  
+  protected void addEitherSetter(final MutableFieldDeclaration field, final String setterName, final EitherTypeArgument argument, @Extension final JsonRpcDataTransformationContext context) {
+    final Procedure1<MutableMethodDeclaration> _function = (MutableMethodDeclaration method) -> {
+      context.setPrimarySourceElement(method, context.getPrimarySourceElement(field));
+      method.addParameter(field.getSimpleName(), argument.getType());
+      method.setStatic(field.isStatic());
+      method.setVisibility(Visibility.PUBLIC);
+      method.setReturnType(context.getPrimitiveVoid());
+      final CompilationStrategy _function_1 = (CompilationStrategy.CompilationContext ctx) -> {
+        return this.compileEitherSetterBody(field, argument, field.getSimpleName(), ctx, context);
+      };
+      method.setBody(_function_1);
+    };
+    field.getDeclaringType().addMethod(setterName, _function);
+  }
+  
+  protected CharSequence compileEitherSetterBody(final MutableFieldDeclaration field, final EitherTypeArgument argument, final String variableName, @Extension final CompilationStrategy.CompilationContext compilationContext, @Extension final JsonRpcDataTransformationContext context) {
+    CharSequence _xblockexpression = null;
+    {
+      AnnotationReference _findAnnotation = field.findAnnotation(context.newTypeReference(NonNull.class).getType());
+      final boolean hasNonNull = (_findAnnotation != null);
+      final String newVariableName = ("_" + variableName);
+      StringConcatenation _builder = new StringConcatenation();
+      String _javaCode = compilationContext.toJavaCode(context.getEitherType());
+      _builder.append(_javaCode);
+      _builder.append(".for");
+      {
+        boolean _isRight = argument.isRight();
+        if (_isRight) {
+          _builder.append("Right");
+        } else {
+          _builder.append("Left");
+        }
+      }
+      _builder.append("(");
+      _builder.append(variableName);
+      _builder.append(")");
+      final CharSequence compileNewEither = _builder;
+      StringConcatenation _builder_1 = new StringConcatenation();
+      _builder_1.append("if (");
+      _builder_1.append(variableName);
+      _builder_1.append(" == null) {");
+      _builder_1.newLineIfNotEmpty();
+      {
+        if (hasNonNull) {
+          _builder_1.append("  ");
+          TypeReference _preconditionsUtil = this.getPreconditionsUtil(field.getDeclaringType(), context);
+          _builder_1.append(_preconditionsUtil, "  ");
+          _builder_1.append(".checkNotNull(");
+          _builder_1.append(variableName, "  ");
+          _builder_1.append(", \"");
+          String _simpleName = field.getSimpleName();
+          _builder_1.append(_simpleName, "  ");
+          _builder_1.append("\");");
+          _builder_1.newLineIfNotEmpty();
+        }
+      }
+      _builder_1.append("  ");
+      _builder_1.append("this.");
+      String _simpleName_1 = field.getSimpleName();
+      _builder_1.append(_simpleName_1, "  ");
+      _builder_1.append(" = null;");
+      _builder_1.newLineIfNotEmpty();
+      _builder_1.append("  ");
+      _builder_1.append("return;");
+      _builder_1.newLine();
+      _builder_1.append("}");
+      _builder_1.newLine();
+      {
+        EitherTypeArgument _parent = argument.getParent();
+        boolean _tripleNotEquals = (_parent != null);
+        if (_tripleNotEquals) {
+          _builder_1.append("final ");
+          String _javaCode_1 = compilationContext.toJavaCode(argument.getParent().getType());
+          _builder_1.append(_javaCode_1);
+          _builder_1.append(" ");
+          _builder_1.append(newVariableName);
+          _builder_1.append(" = ");
+          _builder_1.append(compileNewEither);
+          _builder_1.append(";");
+          _builder_1.newLineIfNotEmpty();
+          CharSequence _compileEitherSetterBody = this.compileEitherSetterBody(field, argument.getParent(), newVariableName, compilationContext, context);
+          _builder_1.append(_compileEitherSetterBody);
+          _builder_1.newLineIfNotEmpty();
+        } else {
+          _builder_1.append("this.");
+          String _simpleName_2 = field.getSimpleName();
+          _builder_1.append(_simpleName_2);
+          _builder_1.append(" = ");
+          _builder_1.append(compileNewEither);
+          _builder_1.append(";");
+          _builder_1.newLineIfNotEmpty();
+        }
+      }
+      _xblockexpression = _builder_1;
+    }
+    return _xblockexpression;
+  }
+  
+  protected MutableMethodDeclaration generateToString(final MutableClassDeclaration impl, @Extension final TransformationContext context) {
+    MutableMethodDeclaration _xblockexpression = null;
+    {
+      final ArrayList<FieldDeclaration> toStringFields = CollectionLiterals.<FieldDeclaration>newArrayList();
+      ClassDeclaration c = impl;
+      do {
+        {
+          Iterable<? extends FieldDeclaration> _declaredFields = c.getDeclaredFields();
+          Iterables.<FieldDeclaration>addAll(toStringFields, _declaredFields);
+          TypeReference _extendedClass = c.getExtendedClass();
+          Type _type = null;
+          if (_extendedClass!=null) {
+            _type=_extendedClass.getType();
+          }
+          c = ((ClassDeclaration) _type);
+        }
+      } while(((c != null) && (!Objects.equal(c, context.getObject()))));
+      final Procedure1<MutableMethodDeclaration> _function = (MutableMethodDeclaration it) -> {
+        it.setReturnType(context.getString());
+        it.addAnnotation(context.newAnnotationReference(Override.class));
+        it.addAnnotation(context.newAnnotationReference(Pure.class));
+        final AccessorsProcessor.Util accessorsUtil = new AccessorsProcessor.Util(context);
+        StringConcatenationClient _client = new StringConcatenationClient() {
+          @Override
+          protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
+            _builder.append(ToStringBuilder.class);
+            _builder.append(" b = new ");
+            _builder.append(ToStringBuilder.class);
+            _builder.append("(this);");
+            _builder.newLineIfNotEmpty();
+            {
+              for(final FieldDeclaration field : toStringFields) {
+                _builder.append("b.add(\"");
+                String _simpleName = field.getSimpleName();
+                _builder.append(_simpleName);
+                _builder.append("\", ");
+                {
+                  TypeDeclaration _declaringType = field.getDeclaringType();
+                  boolean _equals = Objects.equal(_declaringType, impl);
+                  if (_equals) {
+                    _builder.append("this.");
+                    String _simpleName_1 = field.getSimpleName();
+                    _builder.append(_simpleName_1);
+                  } else {
+                    String _getterName = accessorsUtil.getGetterName(field);
+                    _builder.append(_getterName);
+                    _builder.append("()");
+                  }
+                }
+                _builder.append(");");
+                _builder.newLineIfNotEmpty();
+              }
+            }
+            _builder.append("return b.toString();");
+            _builder.newLine();
+          }
+        };
+        it.setBody(_client);
+      };
+      _xblockexpression = impl.addMethod("toString", _function);
+    }
+    return _xblockexpression;
+  }
+  
+  private TypeReference getPreconditionsUtil(final Type type, @Extension final TransformationContext context) {
+    TypeReference _xifexpression = null;
+    boolean _startsWith = type.getQualifiedName().startsWith("org.eclipse.lsp4j.debug");
+    if (_startsWith) {
+      _xifexpression = context.newTypeReference("org.eclipse.lsp4j.debug.util.Preconditions");
+    } else {
+      _xifexpression = context.newTypeReference("org.eclipse.lsp4j.util.Preconditions");
+    }
+    return _xifexpression;
+  }
+}
diff --git a/java/org/eclipse/lsp4j/generator/JsonRpcDataProcessor.xtend b/java/org/eclipse/lsp4j/generator/JsonRpcDataProcessor.xtend
new file mode 100644
index 0000000..ce296a7
--- /dev/null
+++ b/java/org/eclipse/lsp4j/generator/JsonRpcDataProcessor.xtend
@@ -0,0 +1,177 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.generator
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull
+import org.eclipse.xtend.lib.annotations.AccessorsProcessor
+import org.eclipse.xtend.lib.annotations.EqualsHashCodeProcessor
+import org.eclipse.xtend.lib.macro.AbstractClassProcessor
+import org.eclipse.xtend.lib.macro.TransformationContext
+import org.eclipse.xtend.lib.macro.declaration.ClassDeclaration
+import org.eclipse.xtend.lib.macro.declaration.CompilationStrategy.CompilationContext
+import org.eclipse.xtend.lib.macro.declaration.MutableClassDeclaration
+import org.eclipse.xtend.lib.macro.declaration.MutableFieldDeclaration
+import org.eclipse.xtend.lib.macro.declaration.Type
+import org.eclipse.xtend.lib.macro.declaration.Visibility
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder
+import com.google.gson.annotations.JsonAdapter
+
+class JsonRpcDataProcessor extends AbstractClassProcessor {
+
+	override doTransform(MutableClassDeclaration annotatedClass, TransformationContext context) {
+		generateImpl(annotatedClass, context)
+	}
+
+	protected def generateImpl(MutableClassDeclaration impl, extension TransformationContext context) {
+		impl.removeAnnotation(impl.annotations.findFirst [
+			annotationTypeDeclaration == JsonRpcData.findTypeGlobally
+		])
+		impl.generateImplMembers(new JsonRpcDataTransformationContext(context))
+
+		generateToString(impl, context)
+
+		val shouldIncludeSuper = impl.extendedClass.type != Object.newTypeReference.type
+		val equalsHashCodeUtil = new EqualsHashCodeProcessor.Util(context)
+		val fields = impl.declaredFields.filter[!static]
+		equalsHashCodeUtil.addEquals(impl, fields, shouldIncludeSuper)
+		equalsHashCodeUtil.addHashCode(impl, fields, shouldIncludeSuper)
+
+		return impl
+	}
+
+	protected def void generateImplMembers(MutableClassDeclaration impl,
+		extension JsonRpcDataTransformationContext context) {
+		impl.declaredFields.filter [
+			!static
+		].forEach [ field |
+			val accessorsUtil = new AccessorsProcessor.Util(context)
+			val deprecated = field.findAnnotation(Deprecated.findTypeGlobally)
+			accessorsUtil.addGetter(field, Visibility.PUBLIC)
+			val hasNonNull = field.findAnnotation(NonNull.newTypeReference.type) !== null
+			val hasJsonAdapter = field.findAnnotation(JsonAdapter.newTypeReference.type) !== null
+			impl.findDeclaredMethod(accessorsUtil.getGetterName(field)) => [
+				docComment = field.docComment
+				if (hasNonNull) {
+					addAnnotation(newAnnotationReference(NonNull))
+				}
+				if (deprecated !== null)
+					addAnnotation(newAnnotationReference(Deprecated))
+			]
+
+			if (!field.type.inferred) {
+				accessorsUtil.addSetter(field, Visibility.PUBLIC)
+				val setterName = accessorsUtil.getSetterName(field)
+				impl.findDeclaredMethod(setterName, field.type) => [
+					docComment = field.docComment
+					if (hasNonNull) {
+						val parameter = parameters.head
+						parameter.addAnnotation(newAnnotationReference(NonNull))
+						body = '''
+							this.«field.simpleName» = «getPreconditionsUtil(impl, context)».checkNotNull(«parameter.simpleName», "«field.simpleName»");
+						'''
+					}
+					if (deprecated !== null)
+						addAnnotation(newAnnotationReference(Deprecated))
+				]
+				val childTypes = field.type.childTypes
+				if (!childTypes.empty) {
+					val jsonTypes = childTypes.map[type.jsonType].toList
+					if (jsonTypes.size !== jsonTypes.toSet.size) {
+						// If there is a JsonAdapter on the field, the warning is expected to be unneeded because
+						// the adapter will handle the resolution of the either
+						if (!hasJsonAdapter) {
+							field.addWarning('''The json types of an Either must be distinct.''')
+						}
+					} else {
+						for (childType : childTypes) {
+							field.addEitherSetter(setterName, childType, context)
+						}
+					}
+				}
+			}
+		]
+	}
+
+	protected def void addEitherSetter(
+		MutableFieldDeclaration field,
+		String setterName,
+		EitherTypeArgument argument,
+		extension JsonRpcDataTransformationContext context
+	) {
+		field.declaringType.addMethod(setterName) [ method |
+			method.primarySourceElement = field.primarySourceElement
+			method.addParameter(field.simpleName, argument.type)
+			method.static = field.static
+			method.visibility = Visibility.PUBLIC
+			method.returnType = primitiveVoid
+			method.body = [ctx|compileEitherSetterBody(field, argument, field.simpleName, ctx, context)]
+		]
+	}
+
+	protected def CharSequence compileEitherSetterBody(
+		MutableFieldDeclaration field,
+		EitherTypeArgument argument,
+		String variableName,
+		extension CompilationContext compilationContext,
+		extension JsonRpcDataTransformationContext context
+	) {
+		val hasNonNull = field.findAnnotation(NonNull.newTypeReference.type) !== null
+		val newVariableName = '_' + variableName
+		val CharSequence compileNewEither = '''«eitherType.toJavaCode».for«IF argument.right»Right«ELSE»Left«ENDIF»(«variableName»)'''
+		'''
+			if («variableName» == null) {
+			  «IF hasNonNull»
+			  	«getPreconditionsUtil(field.declaringType, context)».checkNotNull(«variableName», "«field.simpleName»");
+			  «ENDIF»
+			  this.«field.simpleName» = null;
+			  return;
+			}
+			«IF argument.parent !== null»
+				final «argument.parent.type.toJavaCode» «newVariableName» = «compileNewEither»;
+				«compileEitherSetterBody(field, argument.parent, newVariableName, compilationContext, context)»
+			«ELSE»
+				this.«field.simpleName» = «compileNewEither»;
+			«ENDIF»
+		'''
+	}
+
+	protected def generateToString(MutableClassDeclaration impl, extension TransformationContext context) {
+		val toStringFields = newArrayList
+		var ClassDeclaration c = impl
+		do {
+			toStringFields += c.declaredFields
+			c = c.extendedClass?.type as ClassDeclaration
+		} while (c !== null && c != object)
+		impl.addMethod("toString") [
+			returnType = string
+			addAnnotation(newAnnotationReference(Override))
+			addAnnotation(newAnnotationReference(Pure))
+			val accessorsUtil = new AccessorsProcessor.Util(context)
+			body = '''
+				«ToStringBuilder» b = new «ToStringBuilder»(this);
+				«FOR field : toStringFields»
+					b.add("«field.simpleName»", «IF field.declaringType == impl»this.«field.simpleName»«ELSE»«
+						accessorsUtil.getGetterName(field)»()«ENDIF»);
+				«ENDFOR»
+				return b.toString();
+			'''
+		]
+	}
+	
+	private def getPreconditionsUtil(Type type, extension TransformationContext context) {
+		if (type.qualifiedName.startsWith('org.eclipse.lsp4j.debug'))
+			newTypeReference('org.eclipse.lsp4j.debug.util.Preconditions')
+		else
+			newTypeReference('org.eclipse.lsp4j.util.Preconditions')
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/generator/JsonRpcDataTransformationContext.java b/java/org/eclipse/lsp4j/generator/JsonRpcDataTransformationContext.java
new file mode 100644
index 0000000..51b380b
--- /dev/null
+++ b/java/org/eclipse/lsp4j/generator/JsonRpcDataTransformationContext.java
@@ -0,0 +1,418 @@
+/**
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.generator;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import org.eclipse.lsp4j.generator.EitherTypeArgument;
+import org.eclipse.lsp4j.generator.JsonType;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.xtend.lib.annotations.AccessorType;
+import org.eclipse.xtend.lib.annotations.Accessors;
+import org.eclipse.xtend.lib.annotations.Delegate;
+import org.eclipse.xtend.lib.macro.TransformationContext;
+import org.eclipse.xtend.lib.macro.declaration.AnnotationReference;
+import org.eclipse.xtend.lib.macro.declaration.Element;
+import org.eclipse.xtend.lib.macro.declaration.InterfaceDeclaration;
+import org.eclipse.xtend.lib.macro.declaration.MutableAnnotationTypeDeclaration;
+import org.eclipse.xtend.lib.macro.declaration.MutableClassDeclaration;
+import org.eclipse.xtend.lib.macro.declaration.MutableElement;
+import org.eclipse.xtend.lib.macro.declaration.MutableEnumerationTypeDeclaration;
+import org.eclipse.xtend.lib.macro.declaration.MutableInterfaceDeclaration;
+import org.eclipse.xtend.lib.macro.declaration.Type;
+import org.eclipse.xtend.lib.macro.declaration.TypeReference;
+import org.eclipse.xtend.lib.macro.file.Path;
+import org.eclipse.xtend.lib.macro.services.AnnotationReferenceBuildContext;
+import org.eclipse.xtend.lib.macro.services.Problem;
+import org.eclipse.xtext.xbase.lib.CollectionLiterals;
+import org.eclipse.xtext.xbase.lib.Functions.Function1;
+import org.eclipse.xtext.xbase.lib.IterableExtensions;
+import org.eclipse.xtext.xbase.lib.Procedures.Procedure0;
+import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
+import org.eclipse.xtext.xbase.lib.Pure;
+
+@SuppressWarnings("all")
+public class JsonRpcDataTransformationContext implements TransformationContext {
+  @Delegate
+  private final TransformationContext delegate;
+  
+  @Accessors(AccessorType.PUBLIC_GETTER)
+  private final TypeReference eitherType;
+  
+  public JsonRpcDataTransformationContext(final TransformationContext delegate) {
+    this.delegate = delegate;
+    this.eitherType = this.newTypeReference(Either.class);
+  }
+  
+  public boolean isEither(final TypeReference typeReference) {
+    return ((typeReference != null) && this.eitherType.isAssignableFrom(typeReference));
+  }
+  
+  public TypeReference getLeftType(final TypeReference typeReference) {
+    final Type type = typeReference.getType();
+    Type _type = this.eitherType.getType();
+    boolean _tripleEquals = (type == _type);
+    if (_tripleEquals) {
+      return IterableExtensions.<TypeReference>head(typeReference.getActualTypeArguments());
+    }
+    if ((type instanceof InterfaceDeclaration)) {
+      final Function1<TypeReference, TypeReference> _function = (TypeReference it) -> {
+        return this.getLeftType(it);
+      };
+      return IterableExtensions.<TypeReference>head(IterableExtensions.<TypeReference>filterNull(IterableExtensions.map(((InterfaceDeclaration)type).getExtendedInterfaces(), _function)));
+    }
+    return null;
+  }
+  
+  public TypeReference getRightType(final TypeReference typeReference) {
+    final Type type = typeReference.getType();
+    Type _type = this.eitherType.getType();
+    boolean _tripleEquals = (type == _type);
+    if (_tripleEquals) {
+      return IterableExtensions.<TypeReference>last(typeReference.getActualTypeArguments());
+    }
+    if ((type instanceof InterfaceDeclaration)) {
+      final Function1<TypeReference, TypeReference> _function = (TypeReference it) -> {
+        return this.getRightType(it);
+      };
+      return IterableExtensions.<TypeReference>head(IterableExtensions.<TypeReference>filterNull(IterableExtensions.map(((InterfaceDeclaration)type).getExtendedInterfaces(), _function)));
+    }
+    return null;
+  }
+  
+  public Collection<EitherTypeArgument> getChildTypes(final TypeReference typeReference) {
+    final ArrayList<EitherTypeArgument> types = CollectionLiterals.<EitherTypeArgument>newArrayList();
+    boolean _isEither = this.isEither(typeReference);
+    if (_isEither) {
+      this.collectChildTypes(this.getLeftType(typeReference), null, false, types);
+      this.collectChildTypes(this.getRightType(typeReference), null, true, types);
+    }
+    return types;
+  }
+  
+  protected void collectChildTypes(final TypeReference type, final EitherTypeArgument parent, final boolean right, final Collection<EitherTypeArgument> types) {
+    final EitherTypeArgument argument = new EitherTypeArgument(type, parent, right);
+    boolean _isEither = this.isEither(type);
+    if (_isEither) {
+      this.collectChildTypes(this.getLeftType(type), argument, false, types);
+      this.collectChildTypes(this.getRightType(type), argument, true, types);
+    } else {
+      if ((type != null)) {
+        types.add(argument);
+      }
+    }
+  }
+  
+  public boolean isJsonNull(final TypeReference type) {
+    JsonType _jsonType = this.getJsonType(type);
+    return (_jsonType == JsonType.NULL);
+  }
+  
+  public boolean isJsonString(final TypeReference type) {
+    JsonType _jsonType = this.getJsonType(type);
+    return (_jsonType == JsonType.STRING);
+  }
+  
+  public boolean isJsonNumber(final TypeReference type) {
+    JsonType _jsonType = this.getJsonType(type);
+    return (_jsonType == JsonType.NUMBER);
+  }
+  
+  public boolean isJsonBoolean(final TypeReference type) {
+    JsonType _jsonType = this.getJsonType(type);
+    return (_jsonType == JsonType.BOOLEAN);
+  }
+  
+  public boolean isJsonArray(final TypeReference type) {
+    JsonType _jsonType = this.getJsonType(type);
+    return (_jsonType == JsonType.ARRAY);
+  }
+  
+  public boolean isJsonObject(final TypeReference type) {
+    JsonType _jsonType = this.getJsonType(type);
+    return (_jsonType == JsonType.OBJECT);
+  }
+  
+  public JsonType getJsonType(final TypeReference type) {
+    if ((type == null)) {
+      return JsonType.NULL;
+    }
+    if ((type.isArray() || this.newTypeReference(List.class).isAssignableFrom(type))) {
+      return JsonType.ARRAY;
+    }
+    if ((this.newTypeReference(Enum.class).isAssignableFrom(type) || this.newTypeReference(Number.class).isAssignableFrom(type))) {
+      return JsonType.NUMBER;
+    }
+    boolean _isAssignableFrom = this.newTypeReference(Boolean.class).isAssignableFrom(type);
+    if (_isAssignableFrom) {
+      return JsonType.BOOLEAN;
+    }
+    if ((this.newTypeReference(String.class).isAssignableFrom(type) || this.newTypeReference(Character.class).isAssignableFrom(type))) {
+      return JsonType.STRING;
+    }
+    boolean _isPrimitive = type.isPrimitive();
+    boolean _not = (!_isPrimitive);
+    if (_not) {
+      return JsonType.OBJECT;
+    }
+    throw new IllegalStateException(("Unexpected type reference: " + type));
+  }
+  
+  public void addError(final Element arg0, final String arg1) {
+    this.delegate.addError(arg0, arg1);
+  }
+  
+  public void addWarning(final Element arg0, final String arg1) {
+    this.delegate.addWarning(arg0, arg1);
+  }
+  
+  public boolean exists(final Path arg0) {
+    return this.delegate.exists(arg0);
+  }
+  
+  public MutableAnnotationTypeDeclaration findAnnotationType(final String arg0) {
+    return this.delegate.findAnnotationType(arg0);
+  }
+  
+  public MutableClassDeclaration findClass(final String arg0) {
+    return this.delegate.findClass(arg0);
+  }
+  
+  public MutableEnumerationTypeDeclaration findEnumerationType(final String arg0) {
+    return this.delegate.findEnumerationType(arg0);
+  }
+  
+  public MutableInterfaceDeclaration findInterface(final String arg0) {
+    return this.delegate.findInterface(arg0);
+  }
+  
+  public Type findTypeGlobally(final Class<?> arg0) {
+    return this.delegate.findTypeGlobally(arg0);
+  }
+  
+  public Type findTypeGlobally(final String arg0) {
+    return this.delegate.findTypeGlobally(arg0);
+  }
+  
+  public TypeReference getAnyType() {
+    return this.delegate.getAnyType();
+  }
+  
+  public String getCharset(final Path arg0) {
+    return this.delegate.getCharset(arg0);
+  }
+  
+  public Iterable<? extends Path> getChildren(final Path arg0) {
+    return this.delegate.getChildren(arg0);
+  }
+  
+  public CharSequence getContents(final Path arg0) {
+    return this.delegate.getContents(arg0);
+  }
+  
+  public InputStream getContentsAsStream(final Path arg0) {
+    return this.delegate.getContentsAsStream(arg0);
+  }
+  
+  public long getLastModification(final Path arg0) {
+    return this.delegate.getLastModification(arg0);
+  }
+  
+  public TypeReference getList(final TypeReference arg0) {
+    return this.delegate.getList(arg0);
+  }
+  
+  public TypeReference getObject() {
+    return this.delegate.getObject();
+  }
+  
+  public Element getPrimaryGeneratedJavaElement(final Element arg0) {
+    return this.delegate.getPrimaryGeneratedJavaElement(arg0);
+  }
+  
+  public Element getPrimarySourceElement(final Element arg0) {
+    return this.delegate.getPrimarySourceElement(arg0);
+  }
+  
+  public TypeReference getPrimitiveBoolean() {
+    return this.delegate.getPrimitiveBoolean();
+  }
+  
+  public TypeReference getPrimitiveByte() {
+    return this.delegate.getPrimitiveByte();
+  }
+  
+  public TypeReference getPrimitiveChar() {
+    return this.delegate.getPrimitiveChar();
+  }
+  
+  public TypeReference getPrimitiveDouble() {
+    return this.delegate.getPrimitiveDouble();
+  }
+  
+  public TypeReference getPrimitiveFloat() {
+    return this.delegate.getPrimitiveFloat();
+  }
+  
+  public TypeReference getPrimitiveInt() {
+    return this.delegate.getPrimitiveInt();
+  }
+  
+  public TypeReference getPrimitiveLong() {
+    return this.delegate.getPrimitiveLong();
+  }
+  
+  public TypeReference getPrimitiveShort() {
+    return this.delegate.getPrimitiveShort();
+  }
+  
+  public TypeReference getPrimitiveVoid() {
+    return this.delegate.getPrimitiveVoid();
+  }
+  
+  public List<? extends Problem> getProblems(final Element arg0) {
+    return this.delegate.getProblems(arg0);
+  }
+  
+  public Path getProjectFolder(final Path arg0) {
+    return this.delegate.getProjectFolder(arg0);
+  }
+  
+  public Set<Path> getProjectSourceFolders(final Path arg0) {
+    return this.delegate.getProjectSourceFolders(arg0);
+  }
+  
+  public TypeReference getSet(final TypeReference arg0) {
+    return this.delegate.getSet(arg0);
+  }
+  
+  public Path getSourceFolder(final Path arg0) {
+    return this.delegate.getSourceFolder(arg0);
+  }
+  
+  public TypeReference getString() {
+    return this.delegate.getString();
+  }
+  
+  public Path getTargetFolder(final Path arg0) {
+    return this.delegate.getTargetFolder(arg0);
+  }
+  
+  public boolean isExternal(final Element arg0) {
+    return this.delegate.isExternal(arg0);
+  }
+  
+  public boolean isFile(final Path arg0) {
+    return this.delegate.isFile(arg0);
+  }
+  
+  public boolean isFolder(final Path arg0) {
+    return this.delegate.isFolder(arg0);
+  }
+  
+  public boolean isGenerated(final Element arg0) {
+    return this.delegate.isGenerated(arg0);
+  }
+  
+  public boolean isSource(final Element arg0) {
+    return this.delegate.isSource(arg0);
+  }
+  
+  public boolean isThePrimaryGeneratedJavaElement(final Element arg0) {
+    return this.delegate.isThePrimaryGeneratedJavaElement(arg0);
+  }
+  
+  public AnnotationReference newAnnotationReference(final AnnotationReference arg0) {
+    return this.delegate.newAnnotationReference(arg0);
+  }
+  
+  public AnnotationReference newAnnotationReference(final AnnotationReference arg0, final Procedure1<AnnotationReferenceBuildContext> arg1) {
+    return this.delegate.newAnnotationReference(arg0, arg1);
+  }
+  
+  public AnnotationReference newAnnotationReference(final Class<?> arg0) {
+    return this.delegate.newAnnotationReference(arg0);
+  }
+  
+  public AnnotationReference newAnnotationReference(final Class<?> arg0, final Procedure1<AnnotationReferenceBuildContext> arg1) {
+    return this.delegate.newAnnotationReference(arg0, arg1);
+  }
+  
+  public AnnotationReference newAnnotationReference(final String arg0) {
+    return this.delegate.newAnnotationReference(arg0);
+  }
+  
+  public AnnotationReference newAnnotationReference(final String arg0, final Procedure1<AnnotationReferenceBuildContext> arg1) {
+    return this.delegate.newAnnotationReference(arg0, arg1);
+  }
+  
+  public AnnotationReference newAnnotationReference(final Type arg0) {
+    return this.delegate.newAnnotationReference(arg0);
+  }
+  
+  public AnnotationReference newAnnotationReference(final Type arg0, final Procedure1<AnnotationReferenceBuildContext> arg1) {
+    return this.delegate.newAnnotationReference(arg0, arg1);
+  }
+  
+  public TypeReference newArrayTypeReference(final TypeReference arg0) {
+    return this.delegate.newArrayTypeReference(arg0);
+  }
+  
+  public TypeReference newSelfTypeReference(final Type arg0) {
+    return this.delegate.newSelfTypeReference(arg0);
+  }
+  
+  public TypeReference newTypeReference(final Class<?> arg0, final TypeReference... arg1) {
+    return this.delegate.newTypeReference(arg0, arg1);
+  }
+  
+  public TypeReference newTypeReference(final String arg0, final TypeReference... arg1) {
+    return this.delegate.newTypeReference(arg0, arg1);
+  }
+  
+  public TypeReference newTypeReference(final Type arg0, final TypeReference... arg1) {
+    return this.delegate.newTypeReference(arg0, arg1);
+  }
+  
+  public TypeReference newWildcardTypeReference() {
+    return this.delegate.newWildcardTypeReference();
+  }
+  
+  public TypeReference newWildcardTypeReference(final TypeReference arg0) {
+    return this.delegate.newWildcardTypeReference(arg0);
+  }
+  
+  public TypeReference newWildcardTypeReferenceWithLowerBound(final TypeReference arg0) {
+    return this.delegate.newWildcardTypeReferenceWithLowerBound(arg0);
+  }
+  
+  public void setPrimarySourceElement(final MutableElement arg0, final Element arg1) {
+    this.delegate.setPrimarySourceElement(arg0, arg1);
+  }
+  
+  public URI toURI(final Path arg0) {
+    return this.delegate.toURI(arg0);
+  }
+  
+  public void validateLater(final Procedure0 arg0) {
+    this.delegate.validateLater(arg0);
+  }
+  
+  @Pure
+  public TypeReference getEitherType() {
+    return this.eitherType;
+  }
+}
diff --git a/java/org/eclipse/lsp4j/generator/JsonRpcDataTransformationContext.xtend b/java/org/eclipse/lsp4j/generator/JsonRpcDataTransformationContext.xtend
new file mode 100644
index 0000000..f89d2fb
--- /dev/null
+++ b/java/org/eclipse/lsp4j/generator/JsonRpcDataTransformationContext.xtend
@@ -0,0 +1,144 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.generator
+
+import java.util.Collection
+import java.util.List
+import org.eclipse.lsp4j.jsonrpc.messages.Either
+import org.eclipse.xtend.lib.annotations.Accessors
+import org.eclipse.xtend.lib.annotations.Delegate
+import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
+import org.eclipse.xtend.lib.macro.TransformationContext
+import org.eclipse.xtend.lib.macro.declaration.InterfaceDeclaration
+import org.eclipse.xtend.lib.macro.declaration.TypeReference
+
+class JsonRpcDataTransformationContext implements TransformationContext {
+
+	@Delegate
+	val TransformationContext delegate
+	@Accessors(PUBLIC_GETTER)
+	val TypeReference eitherType
+
+	new(TransformationContext delegate) {
+		this.delegate = delegate
+		this.eitherType = Either.newTypeReference
+	}
+
+	def boolean isEither(TypeReference typeReference) {
+		return typeReference !== null && eitherType.isAssignableFrom(typeReference)
+	}
+
+	def TypeReference getLeftType(TypeReference typeReference) {
+		val type = typeReference.type
+		if (type === eitherType.type) {
+			return typeReference.actualTypeArguments.head
+		}
+		if (type instanceof InterfaceDeclaration) {
+			return type.extendedInterfaces.map[leftType].filterNull.head
+		}
+		return null
+	}
+
+	def TypeReference getRightType(TypeReference typeReference) {
+		val type = typeReference.type
+		if (type === eitherType.type) {
+			return typeReference.actualTypeArguments.last
+		}
+		if (type instanceof InterfaceDeclaration) {
+			return type.extendedInterfaces.map[rightType].filterNull.head
+		}
+		return null
+	}
+
+	def Collection<EitherTypeArgument> getChildTypes(TypeReference typeReference) {
+		val types = newArrayList
+		if (typeReference.either) {
+			typeReference.leftType.collectChildTypes(null, false, types)
+			typeReference.rightType.collectChildTypes(null, true, types)
+		}
+		return types
+	}
+
+	protected def void collectChildTypes(TypeReference type, EitherTypeArgument parent, boolean right, Collection<EitherTypeArgument> types) {
+		val argument = new EitherTypeArgument(type, parent, right)
+		if (type.either) {
+			type.leftType.collectChildTypes(argument, false, types)
+			type.rightType.collectChildTypes(argument, true, types)
+		} else if (type !== null) {
+			types.add(argument)
+		}
+	}
+
+	def boolean isJsonNull(TypeReference type) {
+		return type.jsonType === JsonType.NULL
+	}
+
+	def boolean isJsonString(TypeReference type) {
+		return type.jsonType === JsonType.STRING
+	}
+
+	def boolean isJsonNumber(TypeReference type) {
+		return type.jsonType === JsonType.NUMBER
+	}
+
+	def boolean isJsonBoolean(TypeReference type) {
+		return type.jsonType === JsonType.BOOLEAN
+	}
+
+	def boolean isJsonArray(TypeReference type) {
+		return type.jsonType === JsonType.ARRAY
+	}
+
+	def boolean isJsonObject(TypeReference type) {
+		return type.jsonType === JsonType.OBJECT
+	}
+
+	def JsonType getJsonType(TypeReference type) {
+		if (type === null) {
+			return JsonType.NULL
+		}
+		if (type.array || List.newTypeReference.isAssignableFrom(type)) {
+			return JsonType.ARRAY
+		}
+		if (Enum.newTypeReference.isAssignableFrom(type) || Number.newTypeReference.isAssignableFrom(type)) {
+			return JsonType.NUMBER
+		}
+		if (Boolean.newTypeReference.isAssignableFrom(type)) {
+			return JsonType.BOOLEAN
+		}
+		if (String.newTypeReference.isAssignableFrom(type) || Character.newTypeReference.isAssignableFrom(type)) {
+			return JsonType.STRING
+		}
+		if (!type.primitive) {
+			return JsonType.OBJECT
+		}
+		throw new IllegalStateException('Unexpected type reference: ' + type)
+	}
+
+}
+
+@Accessors
+@FinalFieldsConstructor
+class EitherTypeArgument {
+	val TypeReference type
+	val EitherTypeArgument parent
+	val boolean right
+}
+
+enum JsonType {
+	NULL,
+	STRING,
+	NUMBER,
+	BOOLEAN,
+	ARRAY,
+	OBJECT
+}
diff --git a/java/org/eclipse/lsp4j/generator/JsonType.java b/java/org/eclipse/lsp4j/generator/JsonType.java
new file mode 100644
index 0000000..06fc0f6
--- /dev/null
+++ b/java/org/eclipse/lsp4j/generator/JsonType.java
@@ -0,0 +1,27 @@
+/**
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.generator;
+
+@SuppressWarnings("all")
+public enum JsonType {
+  NULL,
+  
+  STRING,
+  
+  NUMBER,
+  
+  BOOLEAN,
+  
+  ARRAY,
+  
+  OBJECT;
+}
diff --git a/java/org/eclipse/lsp4j/generator/LanguageServerAPI.java b/java/org/eclipse/lsp4j/generator/LanguageServerAPI.java
new file mode 100644
index 0000000..b39d10a
--- /dev/null
+++ b/java/org/eclipse/lsp4j/generator/LanguageServerAPI.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.generator;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import org.eclipse.lsp4j.generator.JsonRpcDataProcessor;
+import org.eclipse.xtend.lib.macro.Active;
+
+/**
+ * @deprecated use JsonRpcData instead
+ */
+@Deprecated
+@Target(ElementType.TYPE)
+@Active(JsonRpcDataProcessor.class)
+@Retention(RetentionPolicy.SOURCE)
+@SuppressWarnings("all")
+public @interface LanguageServerAPI {
+}
diff --git a/java/org/eclipse/lsp4j/generator/LanguageServerAPI.xtend b/java/org/eclipse/lsp4j/generator/LanguageServerAPI.xtend
new file mode 100644
index 0000000..22fc964
--- /dev/null
+++ b/java/org/eclipse/lsp4j/generator/LanguageServerAPI.xtend
@@ -0,0 +1,27 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.generator
+
+import java.lang.annotation.ElementType
+import java.lang.annotation.Target
+import org.eclipse.xtend.lib.macro.Active
+import java.lang.annotation.Retention
+
+/**
+ * @deprecated use JsonRpcData instead 
+ */
+@Deprecated
+@Target(ElementType.TYPE)
+@Active(JsonRpcDataProcessor)
+@Retention(SOURCE)
+annotation LanguageServerAPI {
+}
diff --git a/java/org/eclipse/lsp4j/generator/TypeAdapterImpl.java b/java/org/eclipse/lsp4j/generator/TypeAdapterImpl.java
new file mode 100644
index 0000000..9c58b53
--- /dev/null
+++ b/java/org/eclipse/lsp4j/generator/TypeAdapterImpl.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.generator;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import org.eclipse.lsp4j.generator.TypeAdapterImplProcessor;
+import org.eclipse.xtend.lib.macro.Active;
+
+/**
+ * Used to simplify the implementation of Gson TypeAdapters.
+ */
+@Target(ElementType.TYPE)
+@Active(TypeAdapterImplProcessor.class)
+@Retention(RetentionPolicy.SOURCE)
+@SuppressWarnings("all")
+public @interface TypeAdapterImpl {
+  public Class<?> value();
+}
diff --git a/java/org/eclipse/lsp4j/generator/TypeAdapterImpl.xtend b/java/org/eclipse/lsp4j/generator/TypeAdapterImpl.xtend
new file mode 100644
index 0000000..1f1ebd6
--- /dev/null
+++ b/java/org/eclipse/lsp4j/generator/TypeAdapterImpl.xtend
@@ -0,0 +1,29 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.generator
+
+import java.lang.annotation.ElementType
+import java.lang.annotation.Retention
+import java.lang.annotation.Target
+import org.eclipse.xtend.lib.macro.Active
+
+/**
+ * Used to simplify the implementation of Gson TypeAdapters.
+ */
+@Target(ElementType.TYPE)
+@Active(TypeAdapterImplProcessor)
+@Retention(SOURCE)
+annotation TypeAdapterImpl {
+	
+	Class<?> value
+	
+}
\ No newline at end of file
diff --git a/java/org/eclipse/lsp4j/generator/TypeAdapterImplProcessor.java b/java/org/eclipse/lsp4j/generator/TypeAdapterImplProcessor.java
new file mode 100644
index 0000000..b9cd39a
--- /dev/null
+++ b/java/org/eclipse/lsp4j/generator/TypeAdapterImplProcessor.java
@@ -0,0 +1,478 @@
+/**
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lsp4j.generator;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.Iterables;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import org.eclipse.lsp4j.generator.TypeAdapterImpl;
+import org.eclipse.xtend.lib.macro.AbstractClassProcessor;
+import org.eclipse.xtend.lib.macro.RegisterGlobalsContext;
+import org.eclipse.xtend.lib.macro.TransformationContext;
+import org.eclipse.xtend.lib.macro.declaration.AnnotationReference;
+import org.eclipse.xtend.lib.macro.declaration.ClassDeclaration;
+import org.eclipse.xtend.lib.macro.declaration.FieldDeclaration;
+import org.eclipse.xtend.lib.macro.declaration.MutableClassDeclaration;
+import org.eclipse.xtend.lib.macro.declaration.MutableConstructorDeclaration;
+import org.eclipse.xtend.lib.macro.declaration.MutableFieldDeclaration;
+import org.eclipse.xtend.lib.macro.declaration.MutableMethodDeclaration;
+import org.eclipse.xtend.lib.macro.declaration.MutableTypeParameterDeclaration;
+import org.eclipse.xtend.lib.macro.declaration.Type;
+import org.eclipse.xtend.lib.macro.declaration.TypeReference;
+import org.eclipse.xtend.lib.macro.declaration.Visibility;
+import org.eclipse.xtend2.lib.StringConcatenationClient;
+import org.eclipse.xtext.xbase.lib.CollectionLiterals;
+import org.eclipse.xtext.xbase.lib.Extension;
+import org.eclipse.xtext.xbase.lib.Functions.Function1;
+import org.eclipse.xtext.xbase.lib.IterableExtensions;
+import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
+import org.eclipse.xtext.xbase.lib.StringExtensions;
+
+@SuppressWarnings("all")
+public class TypeAdapterImplProcessor extends AbstractClassProcessor {
+  @Override
+  public void doRegisterGlobals(final ClassDeclaration annotatedClass, @Extension final RegisterGlobalsContext context) {
+    String _qualifiedName = annotatedClass.getQualifiedName();
+    String _plus = (_qualifiedName + ".Factory");
+    context.registerClass(_plus);
+  }
+  
+  @Override
+  public void doTransform(final MutableClassDeclaration annotatedClass, @Extension final TransformationContext context) {
+    final AnnotationReference typeAdapterImplAnnotation = annotatedClass.findAnnotation(context.findTypeGlobally(TypeAdapterImpl.class));
+    final TypeReference targetType = typeAdapterImplAnnotation.getClassValue("value");
+    this.generateImpl(annotatedClass, targetType, context);
+    String _qualifiedName = annotatedClass.getQualifiedName();
+    String _plus = (_qualifiedName + ".Factory");
+    this.generateFactory(context.findClass(_plus), annotatedClass, targetType, context);
+  }
+  
+  protected MutableClassDeclaration generateImpl(final MutableClassDeclaration impl, final TypeReference targetType, @Extension final TransformationContext context) {
+    final ArrayList<FieldDeclaration> targetFields = this.getTargetFields(targetType, context);
+    final Function1<FieldDeclaration, Boolean> _function = (FieldDeclaration it) -> {
+      return Boolean.valueOf(((!it.getType().isPrimitive()) && (!it.getType().getActualTypeArguments().isEmpty())));
+    };
+    Iterable<FieldDeclaration> _filter = IterableExtensions.<FieldDeclaration>filter(targetFields, _function);
+    for (final FieldDeclaration field : _filter) {
+      String _upperCase = field.getSimpleName().toUpperCase();
+      String _plus = (_upperCase + "_TYPE_TOKEN");
+      final Procedure1<MutableFieldDeclaration> _function_1 = (MutableFieldDeclaration it) -> {
+        it.setFinal(true);
+        it.setStatic(true);
+        it.setType(context.newTypeReference("com.google.gson.reflect.TypeToken", field.getType()));
+        StringConcatenationClient _client = new StringConcatenationClient() {
+          @Override
+          protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
+            _builder.append("new TypeToken<");
+            TypeReference _type = field.getType();
+            _builder.append(_type);
+            _builder.append(">() {}");
+          }
+        };
+        it.setInitializer(_client);
+      };
+      impl.addField(_plus, _function_1);
+    }
+    impl.setExtendedClass(context.newTypeReference("com.google.gson.TypeAdapter", targetType));
+    final Procedure1<MutableFieldDeclaration> _function_2 = (MutableFieldDeclaration it) -> {
+      it.setType(context.newTypeReference("com.google.gson.Gson"));
+      it.setFinal(true);
+    };
+    impl.addField("gson", _function_2);
+    final Procedure1<MutableConstructorDeclaration> _function_3 = (MutableConstructorDeclaration it) -> {
+      it.addParameter("gson", context.newTypeReference("com.google.gson.Gson"));
+      StringConcatenationClient _client = new StringConcatenationClient() {
+        @Override
+        protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
+          _builder.append("this.gson = gson;");
+          _builder.newLine();
+        }
+      };
+      it.setBody(_client);
+    };
+    impl.addConstructor(_function_3);
+    final Procedure1<MutableMethodDeclaration> _function_4 = (MutableMethodDeclaration method) -> {
+      method.addParameter("in", context.newTypeReference("com.google.gson.stream.JsonReader"));
+      method.setExceptions(context.newTypeReference(IOException.class));
+      method.setReturnType(targetType);
+      StringConcatenationClient _client = new StringConcatenationClient() {
+        @Override
+        protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
+          TypeReference _newTypeReference = context.newTypeReference("com.google.gson.stream.JsonToken");
+          _builder.append(_newTypeReference);
+          _builder.append(" nextToken = in.peek();");
+          _builder.newLineIfNotEmpty();
+          _builder.append("if (nextToken == JsonToken.NULL) {");
+          _builder.newLine();
+          _builder.append("\t");
+          _builder.append("return null;");
+          _builder.newLine();
+          _builder.append("}");
+          _builder.newLine();
+          _builder.newLine();
+          _builder.append(targetType);
+          _builder.append(" result = new ");
+          _builder.append(targetType);
+          _builder.append("();");
+          _builder.newLineIfNotEmpty();
+          _builder.append("in.beginObject();");
+          _builder.newLine();
+          _builder.append("while (in.hasNext()) {");
+          _builder.newLine();
+          _builder.append("\t");
+          _builder.append("String name = in.nextName();");
+          _builder.newLine();
+          _builder.append("\t");
+          _builder.append("switch (name) {");
+          _builder.newLine();
+          {
+            for(final FieldDeclaration field : targetFields) {
+              _builder.append("\t");
+              _builder.append("case \"");
+              String _simpleName = field.getSimpleName();
+              _builder.append(_simpleName, "\t");
+              _builder.append("\":");
+              _builder.newLineIfNotEmpty();
+              _builder.append("\t");
+              _builder.append("\t");
+              _builder.append("result.set");
+              String _firstUpper = StringExtensions.toFirstUpper(field.getSimpleName());
+              _builder.append(_firstUpper, "\t\t");
+              _builder.append("(read");
+              String _firstUpper_1 = StringExtensions.toFirstUpper(field.getSimpleName());
+              _builder.append(_firstUpper_1, "\t\t");
+              _builder.append("(in));");
+              _builder.newLineIfNotEmpty();
+              _builder.append("\t");
+              _builder.append("\t");
+              _builder.append("break;");
+              _builder.newLine();
+            }
+          }
+          _builder.append("\t");
+          _builder.append("default:");
+          _builder.newLine();
+          _builder.append("\t\t");
+          _builder.append("in.skipValue();");
+          _builder.newLine();
+          _builder.append("\t");
+          _builder.append("}");
+          _builder.newLine();
+          _builder.append("}");
+          _builder.newLine();
+          _builder.append("in.endObject();");
+          _builder.newLine();
+          _builder.append("return result;");
+          _builder.newLine();
+        }
+      };
+      method.setBody(_client);
+    };
+    impl.addMethod("read", _function_4);
+    for (final FieldDeclaration field_1 : targetFields) {
+      {
+        String _firstUpper = StringExtensions.toFirstUpper(field_1.getSimpleName());
+        String _plus_1 = ("read" + _firstUpper);
+        final MutableMethodDeclaration existingMethod = impl.findDeclaredMethod(_plus_1, 
+          context.newTypeReference("com.google.gson.stream.JsonReader"));
+        if ((existingMethod == null)) {
+          String _firstUpper_1 = StringExtensions.toFirstUpper(field_1.getSimpleName());
+          String _plus_2 = ("read" + _firstUpper_1);
+          final Procedure1<MutableMethodDeclaration> _function_5 = (MutableMethodDeclaration it) -> {
+            it.setVisibility(Visibility.PROTECTED);
+            it.addParameter("in", context.newTypeReference("com.google.gson.stream.JsonReader"));
+            it.setExceptions(context.newTypeReference(IOException.class));
+            it.setReturnType(field_1.getType());
+            boolean _isPrimitive = field_1.getType().isPrimitive();
+            if (_isPrimitive) {
+              String _simpleName = field_1.getType().getSimpleName();
+              if (_simpleName != null) {
+                switch (_simpleName) {
+                  case "boolean":
+                    StringConcatenationClient _client = new StringConcatenationClient() {
+                      @Override
+                      protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
+                        _builder.append("return in.nextBoolean();");
+                      }
+                    };
+                    it.setBody(_client);
+                    break;
+                  case "double":
+                    StringConcatenationClient _client_1 = new StringConcatenationClient() {
+                      @Override
+                      protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
+                        _builder.append("return in.nextDouble();");
+                      }
+                    };
+                    it.setBody(_client_1);
+                    break;
+                  case "float":
+                    StringConcatenationClient _client_2 = new StringConcatenationClient() {
+                      @Override
+                      protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
+                        _builder.append("return (float) in.nextDouble();");
+                      }
+                    };
+                    it.setBody(_client_2);
+                    break;
+                  case "long":
+                    StringConcatenationClient _client_3 = new StringConcatenationClient() {
+                      @Override
+                      protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
+                        _builder.append("return in.nextLong();");
+                      }
+                    };
+                    it.setBody(_client_3);
+                    break;
+                  case "int":
+                    StringConcatenationClient _client_4 = new StringConcatenationClient() {
+                      @Override
+                      protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
+                        _builder.append("return in.nextInt();");
+                      }
+                    };
+                    it.setBody(_client_4);
+                    break;
+                  case "short":
+                  case "byte":
+                  case "char":
+                    StringConcatenationClient _client_5 = new StringConcatenationClient() {
+                      @Override
+                      protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
+                        _builder.append("return (");
+                        TypeReference _type = field_1.getType();
+                        _builder.append(_type);
+                        _builder.append(") in.nextInt();");
+                      }
+                    };
+                    it.setBody(_client_5);
+                    break;
+                }
+              }
+            } else {
+              boolean _isEmpty = field_1.getType().getActualTypeArguments().isEmpty();
+              boolean _not = (!_isEmpty);
+              if (_not) {
+                StringConcatenationClient _client_6 = new StringConcatenationClient() {
+                  @Override
+                  protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
+                    _builder.append("return gson.fromJson(in, ");
+                    String _upperCase = field_1.getSimpleName().toUpperCase();
+                    _builder.append(_upperCase);
+                    _builder.append("_TYPE_TOKEN.getType());");
+                  }
+                };
+                it.setBody(_client_6);
+              } else {
+                StringConcatenationClient _client_7 = new StringConcatenationClient() {
+                  @Override
+                  protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
+                    _builder.append("return gson.fromJson(in, ");
+                    TypeReference _type = field_1.getType();
+                    _builder.append(_type);
+                    _builder.append(".class);");
+                  }
+                };
+                it.setBody(_client_7);
+              }
+            }
+          };
+          impl.addMethod(_plus_2, _function_5);
+        }
+      }
+    }
+    final Procedure1<MutableMethodDeclaration> _function_5 = (MutableMethodDeclaration method) -> {
+      method.addParameter("out", context.newTypeReference("com.google.gson.stream.JsonWriter"));
+      method.addParameter("value", targetType);
+      method.setExceptions(context.newTypeReference(IOException.class));
+      StringConcatenationClient _client = new StringConcatenationClient() {
+        @Override
+        protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
+          _builder.append("if (value == null) {");
+          _builder.newLine();
+          _builder.append("\t");
+          _builder.append("out.nullValue();");
+          _builder.newLine();
+          _builder.append("\t");
+          _builder.append("return;");
+          _builder.newLine();
+          _builder.append("}");
+          _builder.newLine();
+          _builder.newLine();
+          _builder.append("out.beginObject();");
+          _builder.newLine();
+          {
+            for(final FieldDeclaration field : targetFields) {
+              _builder.append("out.name(\"");
+              String _simpleName = field.getSimpleName();
+              _builder.append(_simpleName);
+              _builder.append("\");");
+              _builder.newLineIfNotEmpty();
+              _builder.append("write");
+              String _firstUpper = StringExtensions.toFirstUpper(field.getSimpleName());
+              _builder.append(_firstUpper);
+              _builder.append("(out, value.get");
+              String _firstUpper_1 = StringExtensions.toFirstUpper(field.getSimpleName());
+              _builder.append(_firstUpper_1);
+              _builder.append("());");
+              _builder.newLineIfNotEmpty();
+            }
+          }
+          _builder.append("out.endObject();");
+          _builder.newLine();
+        }
+      };
+      method.setBody(_client);
+    };
+    impl.addMethod("write", _function_5);
+    final Type booleanType = context.findTypeGlobally(Boolean.class);
+    final Type numberType = context.findTypeGlobally(Number.class);
+    final Type stringType = context.findTypeGlobally(String.class);
+    for (final FieldDeclaration field_2 : targetFields) {
+      {
+        String _firstUpper = StringExtensions.toFirstUpper(field_2.getSimpleName());
+        String _plus_1 = ("write" + _firstUpper);
+        final MutableMethodDeclaration existingMethod = impl.findDeclaredMethod(_plus_1, 
+          context.newTypeReference("com.google.gson.stream.JsonWriter"), field_2.getType());
+        if ((existingMethod == null)) {
+          String _firstUpper_1 = StringExtensions.toFirstUpper(field_2.getSimpleName());
+          String _plus_2 = ("write" + _firstUpper_1);
+          final Procedure1<MutableMethodDeclaration> _function_6 = (MutableMethodDeclaration it) -> {
+            it.setVisibility(Visibility.PROTECTED);
+            it.addParameter("out", context.newTypeReference("com.google.gson.stream.JsonWriter"));
+            it.addParameter("value", field_2.getType());
+            it.setExceptions(context.newTypeReference(IOException.class));
+            if ((((field_2.getType().isPrimitive() || booleanType.isAssignableFrom(field_2.getType().getType())) || numberType.isAssignableFrom(field_2.getType().getType())) || stringType.isAssignableFrom(field_2.getType().getType()))) {
+              StringConcatenationClient _client = new StringConcatenationClient() {
+                @Override
+                protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
+                  _builder.append("out.value(value);");
+                  _builder.newLine();
+                }
+              };
+              it.setBody(_client);
+            } else {
+              boolean _isEmpty = field_2.getType().getActualTypeArguments().isEmpty();
+              boolean _not = (!_isEmpty);
+              if (_not) {
+                StringConcatenationClient _client_1 = new StringConcatenationClient() {
+                  @Override
+                  protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
+                    _builder.append("gson.toJson(value, ");
+                    String _upperCase = field_2.getSimpleName().toUpperCase();
+                    _builder.append(_upperCase);
+                    _builder.append("_TYPE_TOKEN.getType(), out);");
+                    _builder.newLineIfNotEmpty();
+                  }
+                };
+                it.setBody(_client_1);
+              } else {
+                TypeReference _type = field_2.getType();
+                TypeReference _newTypeReference = context.newTypeReference(Object.class);
+                boolean _equals = Objects.equal(_type, _newTypeReference);
+                if (_equals) {
+                  StringConcatenationClient _client_2 = new StringConcatenationClient() {
+                    @Override
+                    protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
+                      _builder.append("if (value == null)");
+                      _builder.newLine();
+                      _builder.append("\t");
+                      _builder.append("out.nullValue();");
+                      _builder.newLine();
+                      _builder.append("else");
+                      _builder.newLine();
+                      _builder.append("\t");
+                      _builder.append("gson.toJson(value, value.getClass(), out);");
+                      _builder.newLine();
+                    }
+                  };
+                  it.setBody(_client_2);
+                } else {
+                  StringConcatenationClient _client_3 = new StringConcatenationClient() {
+                    @Override
+                    protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
+                      _builder.append("gson.toJson(value, ");
+                      TypeReference _type = field_2.getType();
+                      _builder.append(_type);
+                      _builder.append(".class, out);");
+                      _builder.newLineIfNotEmpty();
+                    }
+                  };
+                  it.setBody(_client_3);
+                }
+              }
+            }
+          };
+          impl.addMethod(_plus_2, _function_6);
+        }
+      }
+    }
+    return impl;
+  }
+  
+  protected MutableMethodDeclaration generateFactory(final MutableClassDeclaration factory, final MutableClassDeclaration impl, final TypeReference targetType, @Extension final TransformationContext context) {
+    MutableMethodDeclaration _xblockexpression = null;
+    {
+      TypeReference _newTypeReference = context.newTypeReference("com.google.gson.TypeAdapterFactory");
+      factory.setImplementedInterfaces(Collections.<TypeReference>unmodifiableList(CollectionLiterals.<TypeReference>newArrayList(_newTypeReference)));
+      final Procedure1<MutableMethodDeclaration> _function = (MutableMethodDeclaration it) -> {
+        final MutableTypeParameterDeclaration t = it.addTypeParameter("T");
+        it.addParameter("gson", context.newTypeReference("com.google.gson.Gson"));
+        it.addParameter("typeToken", context.newTypeReference("com.google.gson.reflect.TypeToken", context.newTypeReference(t)));
+        it.setReturnType(context.newTypeReference("com.google.gson.TypeAdapter", context.newTypeReference(t)));
+        StringConcatenationClient _client = new StringConcatenationClient() {
+          @Override
+          protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
+            _builder.append("if (!");
+            _builder.append(targetType);
+            _builder.append(".class.isAssignableFrom(typeToken.getRawType())) {");
+            _builder.newLineIfNotEmpty();
+            _builder.append("\t");
+            _builder.append("return null;");
+            _builder.newLine();
+            _builder.append("}");
+            _builder.newLine();
+            _builder.append("return (TypeAdapter<T>) new ");
+            _builder.append(impl);
+            _builder.append("(gson);");
+            _builder.newLineIfNotEmpty();
+          }
+        };
+        it.setBody(_client);
+      };
+      _xblockexpression = factory.addMethod("create", _function);
+    }
+    return _xblockexpression;
+  }
+  
+  private ArrayList<FieldDeclaration> getTargetFields(final TypeReference targetType, @Extension final TransformationContext context) {
+    final Type objectType = context.newTypeReference(Object.class).getType();
+    final ArrayList<FieldDeclaration> targetFields = CollectionLiterals.<FieldDeclaration>newArrayList();
+    TypeReference typeRef = targetType;
+    while ((!Objects.equal(typeRef.getType(), objectType))) {
+      {
+        Type _type = typeRef.getType();
+        final ClassDeclaration clazz = ((ClassDeclaration) _type);
+        final Function1<FieldDeclaration, Boolean> _function = (FieldDeclaration it) -> {
+          boolean _isStatic = it.isStatic();
+          return Boolean.valueOf((!_isStatic));
+        };
+        Iterable<? extends FieldDeclaration> _filter = IterableExtensions.filter(clazz.getDeclaredFields(), _function);
+        Iterables.<FieldDeclaration>addAll(targetFields, _filter);
+        typeRef = clazz.getExtendedClass();
+      }
+    }
+    return targetFields;
+  }
+}
diff --git a/java/org/eclipse/lsp4j/generator/TypeAdapterImplProcessor.xtend b/java/org/eclipse/lsp4j/generator/TypeAdapterImplProcessor.xtend
new file mode 100644
index 0000000..665a7bd
--- /dev/null
+++ b/java/org/eclipse/lsp4j/generator/TypeAdapterImplProcessor.xtend
@@ -0,0 +1,209 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.generator
+
+import java.io.IOException
+import org.eclipse.xtend.lib.macro.AbstractClassProcessor
+import org.eclipse.xtend.lib.macro.RegisterGlobalsContext
+import org.eclipse.xtend.lib.macro.TransformationContext
+import org.eclipse.xtend.lib.macro.declaration.ClassDeclaration
+import org.eclipse.xtend.lib.macro.declaration.MutableClassDeclaration
+import org.eclipse.xtend.lib.macro.declaration.TypeReference
+import org.eclipse.xtend.lib.macro.declaration.Visibility
+
+class TypeAdapterImplProcessor extends AbstractClassProcessor {
+	
+	override doRegisterGlobals(ClassDeclaration annotatedClass, extension RegisterGlobalsContext context) {
+		registerClass(annotatedClass.qualifiedName + '.Factory')
+	}
+
+	override doTransform(MutableClassDeclaration annotatedClass, extension TransformationContext context) {
+		val typeAdapterImplAnnotation = annotatedClass.findAnnotation(TypeAdapterImpl.findTypeGlobally)
+		val targetType = typeAdapterImplAnnotation.getClassValue('value')
+		generateImpl(annotatedClass, targetType, context)
+		generateFactory(findClass(annotatedClass.qualifiedName + '.Factory'), annotatedClass, targetType, context)
+	}
+
+	protected def generateImpl(MutableClassDeclaration impl, TypeReference targetType, extension TransformationContext context) {
+		val targetFields = getTargetFields(targetType, context)
+		for (field : targetFields.filter[!type.isPrimitive && !type.actualTypeArguments.empty]) {
+			impl.addField(field.simpleName.toUpperCase + '_TYPE_TOKEN') [
+				final = true
+				static = true
+				type = newTypeReference('com.google.gson.reflect.TypeToken', field.type)
+				initializer = '''new TypeToken<«field.type»>() {}'''
+			]
+		}
+		
+		impl.extendedClass = newTypeReference('com.google.gson.TypeAdapter', targetType)
+		impl.addField('gson') [
+			type = newTypeReference('com.google.gson.Gson')
+			final = true
+		]
+		impl.addConstructor[
+			addParameter('gson', newTypeReference('com.google.gson.Gson'))
+			body = '''
+				this.gson = gson;
+			'''
+		]
+		
+		impl.addMethod('read') [ method |
+			method.addParameter('in', newTypeReference('com.google.gson.stream.JsonReader'))
+			method.exceptions = newTypeReference(IOException)
+			method.returnType = targetType
+			method.body = '''
+				«newTypeReference('com.google.gson.stream.JsonToken')» nextToken = in.peek();
+				if (nextToken == JsonToken.NULL) {
+					return null;
+				}
+				
+				«targetType» result = new «targetType»();
+				in.beginObject();
+				while (in.hasNext()) {
+					String name = in.nextName();
+					switch (name) {
+					«FOR field : targetFields»
+						case "«field.simpleName»":
+							result.set«field.simpleName.toFirstUpper»(read«field.simpleName.toFirstUpper»(in));
+							break;
+					«ENDFOR»
+					default:
+						in.skipValue();
+					}
+				}
+				in.endObject();
+				return result;
+			'''
+		]
+		
+		for (field : targetFields) {
+			val existingMethod = impl.findDeclaredMethod('read' + field.simpleName.toFirstUpper,
+					newTypeReference('com.google.gson.stream.JsonReader'))
+			if (existingMethod === null) {
+				impl.addMethod('read' + field.simpleName.toFirstUpper) [
+					visibility = Visibility.PROTECTED
+					addParameter('in', newTypeReference('com.google.gson.stream.JsonReader'))
+					exceptions = newTypeReference(IOException)
+					returnType = field.type
+					if (field.type.isPrimitive) {
+						switch field.type.simpleName {
+							case 'boolean':
+								body = '''return in.nextBoolean();'''
+							case 'double':
+								body = '''return in.nextDouble();'''
+							case 'float':
+								body = '''return (float) in.nextDouble();'''
+							case 'long':
+								body = '''return in.nextLong();'''
+							case 'int':
+								body = '''return in.nextInt();'''
+							case 'short', case 'byte', case 'char':
+								body = '''return («field.type») in.nextInt();'''
+						}
+					} else if (!field.type.actualTypeArguments.empty) {
+						body = '''return gson.fromJson(in, «field.simpleName.toUpperCase»_TYPE_TOKEN.getType());'''
+					} else {
+						body = '''return gson.fromJson(in, «field.type».class);'''
+					}
+				]
+			}
+		}
+		
+		impl.addMethod('write') [ method |
+			method.addParameter('out', newTypeReference('com.google.gson.stream.JsonWriter'))
+			method.addParameter('value', targetType)
+			method.exceptions = newTypeReference(IOException)
+			method.body = '''
+				if (value == null) {
+					out.nullValue();
+					return;
+				}
+				
+				out.beginObject();
+				«FOR field : targetFields»
+					out.name("«field.simpleName»");
+					write«field.simpleName.toFirstUpper»(out, value.get«field.simpleName.toFirstUpper»());
+				«ENDFOR»
+				out.endObject();
+			'''
+		]
+		
+		val booleanType = Boolean.findTypeGlobally
+		val numberType = Number.findTypeGlobally
+		val stringType = String.findTypeGlobally
+		for (field : targetFields) {
+			val existingMethod = impl.findDeclaredMethod('write' + field.simpleName.toFirstUpper,
+					newTypeReference('com.google.gson.stream.JsonWriter'), field.type)
+			if (existingMethod === null) {
+				impl.addMethod('write' + field.simpleName.toFirstUpper) [
+					visibility = Visibility.PROTECTED
+					addParameter('out', newTypeReference('com.google.gson.stream.JsonWriter'))
+					addParameter('value', field.type)
+					exceptions = newTypeReference(IOException)
+					if (field.type.isPrimitive || booleanType.isAssignableFrom(field.type.type) || numberType.isAssignableFrom(field.type.type)
+							|| stringType.isAssignableFrom(field.type.type)) {
+						body = '''
+							out.value(value);
+						'''
+					} else if (!field.type.actualTypeArguments.empty) {
+						body = '''
+							gson.toJson(value, «field.simpleName.toUpperCase»_TYPE_TOKEN.getType(), out);
+						'''
+					} else if (field.type == Object.newTypeReference) {
+						body = '''
+							if (value == null)
+								out.nullValue();
+							else
+								gson.toJson(value, value.getClass(), out);
+						'''
+					} else {
+						body = '''
+							gson.toJson(value, «field.type».class, out);
+						'''
+					}
+				]
+			}
+		}
+		
+		return impl
+	}
+	
+	protected def generateFactory(MutableClassDeclaration factory, MutableClassDeclaration impl, TypeReference targetType,
+			extension TransformationContext context) {
+		factory.implementedInterfaces = #[newTypeReference('com.google.gson.TypeAdapterFactory')]
+		factory.addMethod('create') [
+			val t = addTypeParameter('T')
+			addParameter('gson', newTypeReference('com.google.gson.Gson'))
+			addParameter('typeToken', newTypeReference('com.google.gson.reflect.TypeToken', newTypeReference(t)))
+			returnType = newTypeReference('com.google.gson.TypeAdapter', newTypeReference(t))
+			body = '''
+				if (!«targetType».class.isAssignableFrom(typeToken.getRawType())) {
+					return null;
+				}
+				return (TypeAdapter<T>) new «impl»(gson);
+			'''
+		]
+	}
+	
+	private def getTargetFields(TypeReference targetType, extension TransformationContext context) {
+		val objectType = Object.newTypeReference.type
+		val targetFields = newArrayList
+		var typeRef = targetType
+		while (typeRef.type != objectType) {
+			val clazz = typeRef.type as ClassDeclaration
+			targetFields += clazz.declaredFields.filter[!static]
+			typeRef = clazz.extendedClass
+		}
+		return targetFields
+	}
+	
+}
\ No newline at end of file
diff --git a/java/org/eclipse/lsp4j/jsonrpc/CancelChecker.java b/java/org/eclipse/lsp4j/jsonrpc/CancelChecker.java
new file mode 100644
index 0000000..330276b
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/CancelChecker.java
@@ -0,0 +1,39 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc;
+
+import java.util.concurrent.CancellationException;
+
+/**
+ * Used for processing requests with cancellation support.
+ */
+public interface CancelChecker {
+
+	/**
+	 * Throw a {@link CancellationException} if the currently processed request
+	 * has been canceled.
+	 */
+	void checkCanceled();
+
+	/**
+	 * Check for cancellation without throwing an exception.
+	 */
+	default boolean isCanceled() {
+		try {
+			checkCanceled();
+		} catch (CancellationException ce) {
+			return true;
+		}
+		return false;
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/CompletableFutures.java b/java/org/eclipse/lsp4j/jsonrpc/CompletableFutures.java
new file mode 100644
index 0000000..44682f9
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/CompletableFutures.java
@@ -0,0 +1,69 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc;
+
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+import java.util.function.Function;
+
+public final class CompletableFutures {
+	private CompletableFutures() {}
+	
+	/**
+	 * A utility method to create a {@link CompletableFuture} with cancellation support.
+	 * 
+	 * @param code a function that accepts a {@link CancelChecker} and returns the to be computed value
+	 * @return a future
+	 */
+	public static <R> CompletableFuture<R> computeAsync(Function<CancelChecker, R> code) {
+		CompletableFuture<CancelChecker> start = new CompletableFuture<>();
+		CompletableFuture<R> result = start.thenApplyAsync(code);
+		start.complete(new FutureCancelChecker(result));
+		return result;
+	}
+	
+	/**
+	 * A utility method to create a {@link CompletableFuture} with cancellation support.
+	 * 
+	 * @param code a function that accepts a {@link CancelChecker} and returns the to be computed value
+	 * @return a future
+	 */
+	public static <R> CompletableFuture<R> computeAsync(Executor executor, Function<CancelChecker, R> code) {
+		CompletableFuture<CancelChecker> start = new CompletableFuture<>();
+		CompletableFuture<R> result = start.thenApplyAsync(code, executor);
+		start.complete(new FutureCancelChecker(result));
+		return result;
+	}
+	
+	public static class FutureCancelChecker implements CancelChecker {
+		
+		private final CompletableFuture<?> future;
+		
+		public FutureCancelChecker(CompletableFuture<?> future) {
+			this.future = future;
+		}
+
+		@Override
+		public void checkCanceled() {
+			if (future.isCancelled()) 
+				throw new CancellationException();
+		}
+		
+		@Override
+		public boolean isCanceled() {
+			return future.isCancelled();
+		}
+		
+	}
+	
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/Endpoint.java b/java/org/eclipse/lsp4j/jsonrpc/Endpoint.java
new file mode 100644
index 0000000..82cac6c
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/Endpoint.java
@@ -0,0 +1,25 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc;
+
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * An endpoint is a generic interface that accepts jsonrpc requests and notifications.
+ */
+public interface Endpoint {
+
+	CompletableFuture<?> request(String method, Object parameter);
+	
+	void notify(String method, Object parameter);
+	
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/JsonRpcException.java b/java/org/eclipse/lsp4j/jsonrpc/JsonRpcException.java
new file mode 100644
index 0000000..7cbc786
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/JsonRpcException.java
@@ -0,0 +1,44 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.SocketException;
+import java.nio.channels.ClosedChannelException;
+
+/**
+ * An exception thrown when accessing the JSON-RPC communication channel fails.
+ */
+public class JsonRpcException extends RuntimeException {
+	
+	/**
+	 * Whether the given exception indicates that the currently accessed stream has been closed.
+	 */
+	public static boolean indicatesStreamClosed(Throwable thr) {
+		return thr instanceof InterruptedIOException
+				|| thr instanceof ClosedChannelException
+				|| thr instanceof IOException && "Pipe closed".equals(thr.getMessage())
+				|| thr instanceof SocketException && 
+					("Connection reset".equals(thr.getMessage()) || 
+					 "Socket closed".equals(thr.getMessage()) || 
+					 "Broken pipe (Write failed)".equals(thr.getMessage()))
+				|| thr instanceof JsonRpcException && indicatesStreamClosed(thr.getCause());
+	}
+
+	private static final long serialVersionUID = -7952794305289314670L;
+	
+	public JsonRpcException(Throwable cause) {
+		super(cause);
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/Launcher.java b/java/org/eclipse/lsp4j/jsonrpc/Launcher.java
new file mode 100644
index 0000000..b543a73
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/Launcher.java
@@ -0,0 +1,442 @@
+/******************************************************************************
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import org.eclipse.lsp4j.jsonrpc.json.ConcurrentMessageProcessor;
+import org.eclipse.lsp4j.jsonrpc.json.JsonRpcMethod;
+import org.eclipse.lsp4j.jsonrpc.json.JsonRpcMethodProvider;
+import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
+import org.eclipse.lsp4j.jsonrpc.json.StreamMessageConsumer;
+import org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer;
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseError;
+import org.eclipse.lsp4j.jsonrpc.services.ServiceEndpoints;
+import org.eclipse.lsp4j.jsonrpc.validation.ReflectiveMessageValidator;
+
+import com.google.gson.GsonBuilder;
+
+/**
+ * This is the entry point for applications that use LSP4J. A Launcher does all the wiring that is necessary to connect
+ * your endpoint via an input stream and an output stream.
+ * 
+ * @param <T> remote service interface type
+ */
+public interface Launcher<T> {
+	
+	/**
+	 * Create a new Launcher for a given local service object, a given remote interface and an input and output stream.
+	 * 
+	 * @param localService - the object that receives method calls from the remote service
+	 * @param remoteInterface - an interface on which RPC methods are looked up
+	 * @param in - input stream to listen for incoming messages
+	 * @param out - output stream to send outgoing messages
+	 */
+	static <T> Launcher<T> createLauncher(Object localService, Class<T> remoteInterface, InputStream in, OutputStream out) {
+		return new Builder<T>()
+				.setLocalService(localService)
+				.setRemoteInterface(remoteInterface)
+				.setInput(in)
+				.setOutput(out)
+				.create();
+	}
+	
+	/**
+	 * Create a new Launcher for a given local service object, a given remote interface and an input and output stream,
+	 * and set up message validation and tracing.
+	 * 
+	 * @param localService - the object that receives method calls from the remote service
+	 * @param remoteInterface - an interface on which RPC methods are looked up
+	 * @param in - input stream to listen for incoming messages
+	 * @param out - output stream to send outgoing messages
+	 * @param validate - whether messages should be validated with the {@link ReflectiveMessageValidator}
+	 * @param trace - a writer to which incoming and outgoing messages are traced, or {@code null} to disable tracing
+	 */
+	static <T> Launcher<T> createLauncher(Object localService, Class<T> remoteInterface, InputStream in, OutputStream out,
+			boolean validate, PrintWriter trace) {
+		return new Builder<T>()
+				.setLocalService(localService)
+				.setRemoteInterface(remoteInterface)
+				.setInput(in)
+				.setOutput(out)
+				.validateMessages(validate)
+				.traceMessages(trace)
+				.create();
+	}
+	
+	/**
+	 * Create a new Launcher for a given local service object, a given remote interface and an input and output stream.
+	 * Threads are started with the given executor service. The wrapper function is applied to the incoming and
+	 * outgoing message streams so additional message handling such as validation and tracing can be included.
+	 * 
+	 * @param localService - the object that receives method calls from the remote service
+	 * @param remoteInterface - an interface on which RPC methods are looked up
+	 * @param in - input stream to listen for incoming messages
+	 * @param out - output stream to send outgoing messages
+	 * @param executorService - the executor service used to start threads
+	 * @param wrapper - a function for plugging in additional message consumers
+	 */
+	static <T> Launcher<T> createLauncher(Object localService, Class<T> remoteInterface, InputStream in, OutputStream out,
+			ExecutorService executorService, Function<MessageConsumer, MessageConsumer> wrapper) {
+		return createIoLauncher(localService, remoteInterface, in, out, executorService, wrapper);
+	}
+	
+	/**
+	 * Create a new Launcher for a given local service object, a given remote interface and an input and output stream.
+	 * Threads are started with the given executor service. The wrapper function is applied to the incoming and
+	 * outgoing message streams so additional message handling such as validation and tracing can be included.
+	 * 
+	 * @param localService - the object that receives method calls from the remote service
+	 * @param remoteInterface - an interface on which RPC methods are looked up
+	 * @param in - input stream to listen for incoming messages
+	 * @param out - output stream to send outgoing messages
+	 * @param executorService - the executor service used to start threads
+	 * @param wrapper - a function for plugging in additional message consumers
+	 */
+	static <T> Launcher<T> createIoLauncher(Object localService, Class<T> remoteInterface, InputStream in, OutputStream out,
+			ExecutorService executorService, Function<MessageConsumer, MessageConsumer> wrapper) {
+		return new Builder<T>()
+				.setLocalService(localService)
+				.setRemoteInterface(remoteInterface)
+				.setInput(in)
+				.setOutput(out)
+				.setExecutorService(executorService)
+				.wrapMessages(wrapper)
+				.create();
+	}
+	
+	/**
+	 * Create a new Launcher for a given local service object, a given remote interface and an input and output stream.
+	 * Threads are started with the given executor service. The wrapper function is applied to the incoming and
+	 * outgoing message streams so additional message handling such as validation and tracing can be included.
+	 * The {@code configureGson} function can be used to register additional type adapters in the {@link GsonBuilder}
+	 * in order to support protocol classes that cannot be handled by Gson's reflective capabilities.
+	 * 
+	 * @param localService - the object that receives method calls from the remote service
+	 * @param remoteInterface - an interface on which RPC methods are looked up
+	 * @param in - input stream to listen for incoming messages
+	 * @param out - output stream to send outgoing messages
+	 * @param executorService - the executor service used to start threads
+	 * @param wrapper - a function for plugging in additional message consumers
+	 * @param configureGson - a function for Gson configuration
+	 */
+	static <T> Launcher<T> createIoLauncher(Object localService, Class<T> remoteInterface, InputStream in, OutputStream out,
+			ExecutorService executorService, Function<MessageConsumer, MessageConsumer> wrapper, Consumer<GsonBuilder> configureGson) {
+		return new Builder<T>()
+				.setLocalService(localService)
+				.setRemoteInterface(remoteInterface)
+				.setInput(in)
+				.setOutput(out)
+				.setExecutorService(executorService)
+				.wrapMessages(wrapper)
+				.configureGson(configureGson)
+				.create();
+	}
+	
+	/**
+	 * Create a new Launcher for a given local service object, a given remote interface and an input and output stream.
+	 * Threads are started with the given executor service. The wrapper function is applied to the incoming and
+	 * outgoing message streams so additional message handling such as validation and tracing can be included.
+	 * The {@code configureGson} function can be used to register additional type adapters in the {@link GsonBuilder}
+	 * in order to support protocol classes that cannot be handled by Gson's reflective capabilities.
+	 * 
+	 * @param localService - the object that receives method calls from the remote service
+	 * @param remoteInterface - an interface on which RPC methods are looked up
+	 * @param in - input stream to listen for incoming messages
+	 * @param out - output stream to send outgoing messages
+	 * @param validate - whether messages should be validated with the {@link ReflectiveMessageValidator}
+	 * @param executorService - the executor service used to start threads
+	 * @param wrapper - a function for plugging in additional message consumers
+	 * @param configureGson - a function for Gson configuration
+	 */
+	static <T> Launcher<T> createIoLauncher(Object localService, Class<T> remoteInterface, InputStream in, OutputStream out, boolean validate,
+			ExecutorService executorService, Function<MessageConsumer, MessageConsumer> wrapper, Consumer<GsonBuilder> configureGson) {
+		return new Builder<T>()
+				.setLocalService(localService)
+				.setRemoteInterface(remoteInterface)
+				.setInput(in)
+				.setOutput(out)
+				.validateMessages(validate)
+				.setExecutorService(executorService)
+				.wrapMessages(wrapper)
+				.configureGson(configureGson)
+				.create();
+	}
+	
+	/**
+	 * Create a new Launcher for a collection of local service objects, a collection of remote interfaces and an
+	 * input and output stream. Threads are started with the given executor service. The wrapper function is applied
+	 * to the incoming and outgoing message streams so additional message handling such as validation and tracing
+	 * can be included. The {@code configureGson} function can be used to register additional type adapters in
+	 * the {@link GsonBuilder} in order to support protocol classes that cannot be handled by Gson's reflective
+	 * capabilities.
+	 * 
+	 * @param localServices - the objects that receive method calls from the remote services
+	 * @param remoteInterfaces - interfaces on which RPC methods are looked up
+	 * @param classLoader - a class loader that is able to resolve all given interfaces
+	 * @param in - input stream to listen for incoming messages
+	 * @param out - output stream to send outgoing messages
+	 * @param executorService - the executor service used to start threads
+	 * @param wrapper - a function for plugging in additional message consumers
+	 * @param configureGson - a function for Gson configuration
+	 */
+	static Launcher<Object> createIoLauncher(Collection<Object> localServices, Collection<Class<?>> remoteInterfaces, ClassLoader classLoader,
+			InputStream in, OutputStream out, ExecutorService executorService, Function<MessageConsumer, MessageConsumer> wrapper,
+			Consumer<GsonBuilder> configureGson) {
+		return new Builder<Object>()
+				.setLocalServices(localServices)
+				.setRemoteInterfaces(remoteInterfaces)
+				.setClassLoader(classLoader)
+				.setInput(in)
+				.setOutput(out)
+				.setExecutorService(executorService)
+				.wrapMessages(wrapper)
+				.configureGson(configureGson)
+				.create();
+	}
+	
+	
+	//------------------------------ Builder Class ------------------------------//
+	
+	/**
+	 * The launcher builder wires up all components for JSON-RPC communication.
+	 * 
+	 * @param <T> remote service interface type
+	 */
+	public static class Builder<T> {
+		
+		protected Collection<Object> localServices;
+		protected Collection<Class<? extends T>> remoteInterfaces;
+		protected InputStream input;
+		protected OutputStream output;
+		protected ExecutorService executorService;
+		protected Function<MessageConsumer, MessageConsumer> messageWrapper;
+		protected Function<Throwable, ResponseError> exceptionHandler;
+		protected boolean validateMessages;
+		protected Consumer<GsonBuilder> configureGson;
+		protected ClassLoader classLoader;
+		protected MessageTracer messageTracer;
+		
+		public Builder<T> setLocalService(Object localService) {
+			this.localServices = Collections.singletonList(localService);
+			return this;
+		}
+
+		public Builder<T> setLocalServices(Collection<Object> localServices) {
+			this.localServices = localServices;
+			return this;
+		}
+
+		public Builder<T> setRemoteInterface(Class<? extends T> remoteInterface) {
+			this.remoteInterfaces = Collections.singletonList(remoteInterface);
+			return this;
+		}
+		
+		public Builder<T> setRemoteInterfaces(Collection<Class<? extends T>> remoteInterfaces) {
+			this.remoteInterfaces = remoteInterfaces;
+			return this;
+		}
+
+		public Builder<T> setInput(InputStream input) {
+			this.input = input;
+			return this;
+		}
+
+		public Builder<T> setOutput(OutputStream output) {
+			this.output = output;
+			return this;
+		}
+
+		public Builder<T> setExecutorService(ExecutorService executorService) {
+			this.executorService = executorService;
+			return this;
+		}
+
+		public Builder<T> setClassLoader(ClassLoader classLoader) {
+			this.classLoader = classLoader;
+			return this;
+		}
+
+		public Builder<T> wrapMessages(Function<MessageConsumer, MessageConsumer> wrapper) {
+			this.messageWrapper = wrapper;
+			return this;
+		}
+		
+		public Builder<T> setExceptionHandler(Function<Throwable, ResponseError> exceptionHandler) {
+			this.exceptionHandler = exceptionHandler;
+			return this;
+		}
+		
+		public Builder<T> validateMessages(boolean validate) {
+			this.validateMessages = validate;
+			return this;
+		}
+		
+		public Builder<T> traceMessages(PrintWriter tracer) {
+			if (tracer != null) {
+				this.messageTracer = new MessageTracer(tracer);
+			}
+			return this;
+		}
+
+		public Builder<T> configureGson(Consumer<GsonBuilder> configureGson) {
+			this.configureGson = configureGson;
+			return this;
+		}
+
+		public Launcher<T> create() {
+			// Validate input
+			if (input == null)
+				throw new IllegalStateException("Input stream must be configured.");
+			if (output == null)
+				throw new IllegalStateException("Output stream must be configured.");
+			if (localServices == null)
+				throw new IllegalStateException("Local service must be configured.");
+			if (remoteInterfaces == null)
+				throw new IllegalStateException("Remote interface must be configured.");
+			
+			// Create the JSON handler, remote endpoint and remote proxy
+			MessageJsonHandler jsonHandler = createJsonHandler();
+			RemoteEndpoint remoteEndpoint = createRemoteEndpoint(jsonHandler);
+			T remoteProxy = createProxy(remoteEndpoint);
+			
+			// Create the message processor
+			StreamMessageProducer reader = new StreamMessageProducer(input, jsonHandler, remoteEndpoint);
+			MessageConsumer messageConsumer = wrapMessageConsumer(remoteEndpoint);
+			ConcurrentMessageProcessor msgProcessor = createMessageProcessor(reader, messageConsumer, remoteProxy);
+			ExecutorService execService = executorService != null ? executorService : Executors.newCachedThreadPool();
+			return createLauncher(execService, remoteProxy, remoteEndpoint, msgProcessor);
+		}
+		
+		/**
+		 * Create the JSON handler for messages between the local and remote services.
+		 */
+		protected MessageJsonHandler createJsonHandler() {
+			Map<String, JsonRpcMethod> supportedMethods = getSupportedMethods();
+			if (configureGson != null)
+				return new MessageJsonHandler(supportedMethods, configureGson);
+			else
+				return new MessageJsonHandler(supportedMethods);
+		}
+		
+		/**
+		 * Create the remote endpoint that communicates with the local services.
+		 */
+		protected RemoteEndpoint createRemoteEndpoint(MessageJsonHandler jsonHandler) {
+			MessageConsumer outgoingMessageStream = new StreamMessageConsumer(output, jsonHandler);
+			outgoingMessageStream = wrapMessageConsumer(outgoingMessageStream);
+			Endpoint localEndpoint = ServiceEndpoints.toEndpoint(localServices);
+			RemoteEndpoint remoteEndpoint;
+			if (exceptionHandler == null)
+				remoteEndpoint = new RemoteEndpoint(outgoingMessageStream, localEndpoint);
+			else
+				remoteEndpoint = new RemoteEndpoint(outgoingMessageStream, localEndpoint, exceptionHandler);
+			jsonHandler.setMethodProvider(remoteEndpoint);
+			return remoteEndpoint;
+		}
+		
+		/**
+		 * Create the proxy for calling methods on the remote service.
+		 */
+		@SuppressWarnings("unchecked")
+		protected T createProxy(RemoteEndpoint remoteEndpoint) {
+			if (localServices.size() == 1 && remoteInterfaces.size() == 1) {
+				return ServiceEndpoints.toServiceObject(remoteEndpoint, remoteInterfaces.iterator().next());
+			} else {
+				return (T) ServiceEndpoints.toServiceObject(remoteEndpoint, (Collection<Class<?>>) (Object) remoteInterfaces, classLoader);
+			}
+		}
+		
+		/**
+		 * Create the message processor that listens to the input stream. 
+		 */
+		protected ConcurrentMessageProcessor createMessageProcessor(MessageProducer reader, 
+				MessageConsumer messageConsumer, T remoteProxy) {
+			return new ConcurrentMessageProcessor(reader, messageConsumer);
+		}
+		
+		protected Launcher<T> createLauncher(ExecutorService execService, T remoteProxy, RemoteEndpoint remoteEndpoint,
+				ConcurrentMessageProcessor msgProcessor) {
+			return new StandardLauncher<T>(execService, remoteProxy, remoteEndpoint, msgProcessor);
+		}
+		
+		protected MessageConsumer wrapMessageConsumer(MessageConsumer consumer) {
+			MessageConsumer result = consumer;
+			if (messageTracer != null) {
+				result = messageTracer.apply(consumer);
+			}
+			if (validateMessages) {
+				result = new ReflectiveMessageValidator(result);
+			}
+			if (messageWrapper != null) {
+				result = messageWrapper.apply(result);
+			}
+			return result;
+		}
+		
+		/**
+		 * Gather all JSON-RPC methods from the local and remote services.
+		 */
+		protected Map<String, JsonRpcMethod> getSupportedMethods() {
+			Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+			// Gather the supported methods of remote interfaces
+			for (Class<?> interface_ : remoteInterfaces) {
+				supportedMethods.putAll(ServiceEndpoints.getSupportedMethods(interface_));
+			}
+			
+			// Gather the supported methods of local services
+			for (Object localService : localServices) {
+				if (localService instanceof JsonRpcMethodProvider) {
+					JsonRpcMethodProvider rpcMethodProvider = (JsonRpcMethodProvider) localService;
+					supportedMethods.putAll(rpcMethodProvider.supportedMethods());
+				} else {
+					supportedMethods.putAll(ServiceEndpoints.getSupportedMethods(localService.getClass()));
+				}
+			}
+			
+			return supportedMethods;
+		}
+	}
+	
+	
+	//---------------------------- Interface Methods ----------------------------//
+	
+	/**
+	 * Start a thread that listens to the input stream. The thread terminates when the stream is closed.
+	 * 
+	 * @return a future that returns {@code null} when the listener thread is terminated
+	 */
+	Future<Void> startListening();
+	
+	/**
+	 * Returns the proxy instance that implements the remote service interfaces.
+	 */
+	T getRemoteProxy();
+	
+	/**
+	 * Returns the remote endpoint. Use this one to send generic {@code request} or {@code notify} methods
+	 * to the remote services.
+	 */
+	RemoteEndpoint getRemoteEndpoint();
+	
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/MessageConsumer.java b/java/org/eclipse/lsp4j/jsonrpc/MessageConsumer.java
new file mode 100644
index 0000000..eb49465
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/MessageConsumer.java
@@ -0,0 +1,26 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc;
+
+import org.eclipse.lsp4j.jsonrpc.messages.Message;
+
+public interface MessageConsumer {
+	
+	/**
+	 * Consume a single message.
+	 * 
+	 * @throws MessageIssueException when an issue is found that prevents further processing of the message
+	 * @throws JsonRpcException when accessing the JSON-RPC communication channel fails
+	 */
+	void consume(Message message) throws MessageIssueException, JsonRpcException;
+	
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/MessageIssueException.java b/java/org/eclipse/lsp4j/jsonrpc/MessageIssueException.java
new file mode 100644
index 0000000..58dec38
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/MessageIssueException.java
@@ -0,0 +1,64 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.eclipse.lsp4j.jsonrpc.messages.Message;
+import org.eclipse.lsp4j.jsonrpc.messages.MessageIssue;
+
+/**
+ * An exception thrown to notify the caller of a {@link MessageConsumer} that one or more issues were
+ * found while parsing or validating a message. This information can be passed to a {@link MessageIssueHandler}
+ * in order to construct a proper response.
+ */
+public class MessageIssueException extends RuntimeException {
+	
+	private static final long serialVersionUID = 1118210473728652711L;
+	
+	private final Message rpcMessage;
+	private final List<MessageIssue> issues;
+
+	public MessageIssueException(Message rpcMessage, MessageIssue issue) {
+		this.rpcMessage = rpcMessage;
+		this.issues = Collections.singletonList(issue);
+	}
+
+	public MessageIssueException(Message rpcMessage, Collection<MessageIssue> issues) {
+		this.rpcMessage = rpcMessage;
+		this.issues = Collections.unmodifiableList(new ArrayList<>(issues));
+	}
+	
+	public MessageIssueException(Message rpcMessage, Stream<MessageIssue> issueStream) {
+		this.rpcMessage = rpcMessage;
+		this.issues = Collections.unmodifiableList(issueStream.collect(Collectors.toList()));
+	}
+
+	@Override
+	public String getMessage() {
+		return issues.stream().map(issue -> issue.getText()).collect(Collectors.joining("\n"));
+	}
+	
+	public Message getRpcMessage() {
+		return rpcMessage;
+	}
+	
+	public List<MessageIssue> getIssues() {
+		return issues;
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/MessageIssueHandler.java b/java/org/eclipse/lsp4j/jsonrpc/MessageIssueHandler.java
new file mode 100644
index 0000000..768465b
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/MessageIssueHandler.java
@@ -0,0 +1,26 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc;
+
+import java.util.List;
+
+import org.eclipse.lsp4j.jsonrpc.messages.Message;
+import org.eclipse.lsp4j.jsonrpc.messages.MessageIssue;
+
+public interface MessageIssueHandler {
+	
+	/**
+	 * Handle issues found while parsing or validating a message. The list of issues must not be empty.
+	 */
+	void handle(Message message, List<MessageIssue> issues);
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/MessageProducer.java b/java/org/eclipse/lsp4j/jsonrpc/MessageProducer.java
new file mode 100644
index 0000000..30b2e51
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/MessageProducer.java
@@ -0,0 +1,24 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc;
+
+public interface MessageProducer {
+	
+	/**
+	 * Listen to a message source and forward all messages to the given consumer. Typically this method
+	 * blocks until the message source is unable to deliver more messages.
+	 * 
+	 * @throws JsonRpcException when accessing the JSON-RPC communication channel fails
+	 */
+	void listen(MessageConsumer messageConsumer) throws JsonRpcException;
+	
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/MessageTracer.java b/java/org/eclipse/lsp4j/jsonrpc/MessageTracer.java
new file mode 100644
index 0000000..8398f6f
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/MessageTracer.java
@@ -0,0 +1,41 @@
+/******************************************************************************
+ * Copyright (c) 2016-2019 TypeFox and others.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc;
+
+import org.eclipse.lsp4j.jsonrpc.TracingMessageConsumer.RequestMetadata;
+
+import java.io.PrintWriter;
+import java.time.Clock;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Function;
+
+/**
+ * Wraps a {@link MessageConsumer} with one that logs in a way that the LSP Inspector can parse. *
+ * https://microsoft.github.io/language-server-protocol/inspector/
+ */
+public class MessageTracer implements Function<MessageConsumer, MessageConsumer> {
+	private final PrintWriter printWriter;
+	private final Map<String, RequestMetadata> sentRequests = new HashMap<>();
+	private final Map<String, RequestMetadata> receivedRequests = new HashMap<>();
+
+	MessageTracer(PrintWriter printWriter) {
+		this.printWriter = Objects.requireNonNull(printWriter);
+	}
+
+	@Override
+	public MessageConsumer apply(MessageConsumer messageConsumer) {
+		return new TracingMessageConsumer(
+				messageConsumer, sentRequests, receivedRequests, printWriter, Clock.systemDefaultZone());
+	}
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/RemoteEndpoint.java b/java/org/eclipse/lsp4j/jsonrpc/RemoteEndpoint.java
new file mode 100644
index 0000000..0907da8
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/RemoteEndpoint.java
@@ -0,0 +1,399 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Function;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.eclipse.lsp4j.jsonrpc.json.MessageConstants;
+import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
+import org.eclipse.lsp4j.jsonrpc.json.MethodProvider;
+import org.eclipse.lsp4j.jsonrpc.messages.CancelParams;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.messages.Message;
+import org.eclipse.lsp4j.jsonrpc.messages.MessageIssue;
+import org.eclipse.lsp4j.jsonrpc.messages.NotificationMessage;
+import org.eclipse.lsp4j.jsonrpc.messages.RequestMessage;
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseError;
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseErrorCode;
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage;
+
+/**
+ * An endpoint that can be used to send messages to a given {@link MessageConsumer} by calling
+ * {@link #request(String, Object)} or {@link #notify(String, Object)}. When connected to a {@link MessageProducer},
+ * this class forwards received messages to the local {@link Endpoint} given in the constructor.
+ */
+public class RemoteEndpoint implements Endpoint, MessageConsumer, MessageIssueHandler, MethodProvider {
+
+	private static final Logger LOG = Logger.getLogger(RemoteEndpoint.class.getName());
+	
+	public static final Function<Throwable, ResponseError> DEFAULT_EXCEPTION_HANDLER = (throwable) -> {
+		if (throwable instanceof ResponseErrorException) {
+			return ((ResponseErrorException) throwable).getResponseError();
+		} else if ((throwable instanceof CompletionException || throwable instanceof InvocationTargetException)
+				&& throwable.getCause() instanceof ResponseErrorException) {
+			return ((ResponseErrorException) throwable.getCause()).getResponseError();
+		} else {
+			return fallbackResponseError("Internal error", throwable);
+		}
+	};
+
+	private static ResponseError fallbackResponseError(String header, Throwable throwable) {
+		LOG.log(Level.SEVERE, header + ": " + throwable.getMessage(), throwable);
+		ResponseError error = new ResponseError();
+		error.setMessage(header + ".");
+		error.setCode(ResponseErrorCode.InternalError);
+		ByteArrayOutputStream stackTrace = new ByteArrayOutputStream();
+		PrintWriter stackTraceWriter = new PrintWriter(stackTrace);
+		throwable.printStackTrace(stackTraceWriter);
+		stackTraceWriter.flush();
+		error.setData(stackTrace.toString());
+		return error;
+	}
+
+	private final MessageConsumer out;
+	private final Endpoint localEndpoint;
+	private final Function<Throwable, ResponseError> exceptionHandler;
+	
+	private final AtomicInteger nextRequestId = new AtomicInteger();
+	private final Map<String, PendingRequestInfo> sentRequestMap = new LinkedHashMap<>();
+	private final Map<String, CompletableFuture<?>> receivedRequestMap = new LinkedHashMap<>();
+	
+	/**
+	 * Information about requests that have been sent and for which no response has been received yet.
+	 */
+	private static class PendingRequestInfo {
+		PendingRequestInfo(RequestMessage requestMessage2, CompletableFuture<Object> future2) {
+			this.requestMessage = requestMessage2;
+			this.future = future2;
+		}
+		RequestMessage requestMessage;
+		CompletableFuture<Object> future;
+	}
+	
+	/**
+	 * @param out - a consumer that transmits messages to the remote service
+	 * @param localEndpoint - the local service implementation
+	 * @param exceptionHandler - an exception handler that should never return null.
+	 */
+	public RemoteEndpoint(MessageConsumer out, Endpoint localEndpoint, Function<Throwable, ResponseError> exceptionHandler) {
+		if (out == null)
+			throw new NullPointerException("out");
+		if (localEndpoint == null)
+			throw new NullPointerException("localEndpoint");
+		if (exceptionHandler == null)
+			throw new NullPointerException("exceptionHandler");
+		this.out = out;
+		this.localEndpoint = localEndpoint;
+		this.exceptionHandler = exceptionHandler;
+	}
+	
+	/**
+	 * @param out - a consumer that transmits messages to the remote service
+	 * @param localEndpoint - the local service implementation
+	 */
+	public RemoteEndpoint(MessageConsumer out, Endpoint localEndpoint) {
+		this(out, localEndpoint, DEFAULT_EXCEPTION_HANDLER);
+	}
+
+	/**
+	 * Send a notification to the remote endpoint.
+	 */
+	@Override
+	public void notify(String method, Object parameter) {
+		NotificationMessage notificationMessage = createNotificationMessage(method, parameter);
+		try {
+			out.consume(notificationMessage);
+		} catch (Exception exception) {
+			Level logLevel = JsonRpcException.indicatesStreamClosed(exception) ? Level.INFO : Level.WARNING;
+			LOG.log(logLevel, "Failed to send notification message.", exception);
+		}
+	}
+
+	protected NotificationMessage createNotificationMessage(String method, Object parameter) {
+		NotificationMessage notificationMessage = new NotificationMessage();
+		notificationMessage.setJsonrpc(MessageConstants.JSONRPC_VERSION);
+		notificationMessage.setMethod(method);
+		notificationMessage.setParams(parameter);
+		return notificationMessage;
+	}
+
+	/**
+	 * Send a request to the remote endpoint.
+	 */
+	@Override
+	public CompletableFuture<Object> request(String method, Object parameter) {
+		final RequestMessage requestMessage = createRequestMessage(method, parameter);
+		final CompletableFuture<Object> result = new CompletableFuture<Object>() {
+			@Override
+			public boolean cancel(boolean mayInterruptIfRunning) {
+				sendCancelNotification(requestMessage.getRawId());
+				return super.cancel(mayInterruptIfRunning);
+			}
+		};
+		synchronized(sentRequestMap) {
+			// Store request information so it can be handled when the response is received
+			sentRequestMap.put(requestMessage.getId(), new PendingRequestInfo(requestMessage, result));
+		}
+		
+		try {
+			// Send the request to the remote service
+			out.consume(requestMessage);
+		} catch (Exception exception) {
+			// The message could not be sent, e.g. because the communication channel was closed
+			result.completeExceptionally(exception);
+		}
+		return result;
+	}
+
+	protected RequestMessage createRequestMessage(String method, Object parameter) {
+		RequestMessage requestMessage = new RequestMessage();
+		requestMessage.setId(String.valueOf(nextRequestId.incrementAndGet()));
+		requestMessage.setMethod(method);
+		requestMessage.setParams(parameter);
+		return requestMessage;
+	}
+
+	protected void sendCancelNotification(Either<String, Number> id) {
+		CancelParams cancelParams = new CancelParams();
+		cancelParams.setRawId(id);
+		notify(MessageJsonHandler.CANCEL_METHOD.getMethodName(), cancelParams);
+	}
+
+	@Override
+	public void consume(Message message) {
+		if (message instanceof NotificationMessage) {
+			NotificationMessage notificationMessage = (NotificationMessage) message;
+			handleNotification(notificationMessage);
+		} else if (message instanceof RequestMessage) {
+			RequestMessage requestMessage = (RequestMessage) message;
+			handleRequest(requestMessage);
+		} else if (message instanceof ResponseMessage) {
+			ResponseMessage responseMessage = (ResponseMessage) message;
+			handleResponse(responseMessage);
+		} else {
+			LOG.log(Level.WARNING, "Unkown message type.", message);
+		}
+	}
+
+	protected void handleResponse(ResponseMessage responseMessage) {
+		PendingRequestInfo requestInfo;
+		synchronized (sentRequestMap) {
+			requestInfo = sentRequestMap.remove(responseMessage.getId());
+		}
+		if (requestInfo == null) {
+			// We have no pending request information that matches the id given in the response
+			LOG.log(Level.WARNING, "Unmatched response message: " + responseMessage);
+		} else if (responseMessage.getError() != null) {
+			// The remote service has replied with an error
+			requestInfo.future.completeExceptionally(new ResponseErrorException(responseMessage.getError()));
+		} else {
+			// The remote service has replied with a result object
+			requestInfo.future.complete(responseMessage.getResult());
+		}
+	}
+
+	protected void handleNotification(NotificationMessage notificationMessage) {
+		if (!handleCancellation(notificationMessage)) {
+			// Forward the notification to the local endpoint
+			try {
+				localEndpoint.notify(notificationMessage.getMethod(), notificationMessage.getParams());
+			} catch (Exception exception) {
+				LOG.log(Level.WARNING, "Notification threw an exception: " + notificationMessage, exception);
+			}
+		}
+	}
+	
+	/**
+	 * Cancellation is handled inside this class and not forwarded to the local endpoint.
+	 * 
+	 * @return {@code true} if the given message is a cancellation notification,
+	 *         {@code false} if it can be handled by the local endpoint
+	 */
+	protected boolean handleCancellation(NotificationMessage notificationMessage) {
+		if (MessageJsonHandler.CANCEL_METHOD.getMethodName().equals(notificationMessage.getMethod())) {
+			Object cancelParams = notificationMessage.getParams();
+			if (cancelParams != null) {
+				if (cancelParams instanceof CancelParams) {
+					synchronized (receivedRequestMap) {
+						String id = ((CancelParams) cancelParams).getId();
+						CompletableFuture<?> future = receivedRequestMap.get(id);
+						if (future != null)
+							future.cancel(true);
+						else
+							LOG.warning("Unmatched cancel notification for request id " + id);
+					}
+					return true;
+				} else {
+					LOG.warning("Cancellation support is disabled, since the '" + MessageJsonHandler.CANCEL_METHOD.getMethodName() + "' method has been registered explicitly.");
+				}
+			} else {
+				LOG.warning("Missing 'params' attribute of cancel notification.");
+			}
+		}
+		return false;
+	}
+	
+	protected void handleRequest(RequestMessage requestMessage) {
+		CompletableFuture<?> future;
+		try {
+			// Forward the request to the local endpoint
+			future = localEndpoint.request(requestMessage.getMethod(), requestMessage.getParams());
+		} catch (Throwable throwable) {
+			// The local endpoint has failed handling the request - reply with an error response
+			ResponseError errorObject = exceptionHandler.apply(throwable);
+			if (errorObject == null) {
+				errorObject = fallbackResponseError("Internal error. Exception handler provided no error object", throwable);
+			}
+			out.consume(createErrorResponseMessage(requestMessage, errorObject));
+			if (throwable instanceof Error)
+				throw (Error) throwable;
+			else
+				return;
+		}
+		
+		final String messageId = requestMessage.getId();
+		synchronized (receivedRequestMap) {
+			receivedRequestMap.put(messageId, future);
+		}
+		future.thenAccept((result) -> {
+			// Reply with the result object that was computed by the local endpoint 
+			out.consume(createResultResponseMessage(requestMessage, result));
+		}).exceptionally((Throwable t) -> {
+			// The local endpoint has failed computing a result - reply with an error response
+			ResponseMessage responseMessage;
+			if (isCancellation(t)) {
+				String message = "The request (id: " + messageId + ", method: '" + requestMessage.getMethod()  + "') has been cancelled";
+				ResponseError errorObject = new ResponseError(ResponseErrorCode.RequestCancelled, message, null);
+				responseMessage = createErrorResponseMessage(requestMessage, errorObject);
+			} else {
+				ResponseError errorObject = exceptionHandler.apply(t);
+				if (errorObject == null) {
+					errorObject = fallbackResponseError("Internal error. Exception handler provided no error object", t);
+				}
+				responseMessage = createErrorResponseMessage(requestMessage, errorObject);
+			}
+			out.consume(responseMessage);
+			return null;
+		}).thenApply((obj) -> {
+			synchronized (receivedRequestMap) {
+				receivedRequestMap.remove(messageId);
+			}
+			return null;
+		});
+	}
+
+	@Override
+	public void handle(Message message, List<MessageIssue> issues) {
+		if (issues.isEmpty()) {
+			throw new IllegalArgumentException("The list of issues must not be empty.");
+		}
+		
+		if (message instanceof RequestMessage) {
+			RequestMessage requestMessage = (RequestMessage) message;
+			handleRequestIssues(requestMessage, issues);
+		} else if (message instanceof ResponseMessage) {
+			ResponseMessage responseMessage = (ResponseMessage) message;
+			handleResponseIssues(responseMessage, issues);
+		} else {
+			logIssues(message, issues);
+		}
+	}
+	
+	protected void logIssues(Message message, List<MessageIssue> issues) {
+		for (MessageIssue issue : issues) {
+			String logMessage = "Issue found in " + message.getClass().getSimpleName() + ": " + issue.getText();
+			LOG.log(Level.WARNING, logMessage, issue.getCause());
+		}
+	}
+	
+	protected void handleRequestIssues(RequestMessage requestMessage, List<MessageIssue> issues) {
+		ResponseError errorObject = new ResponseError();
+		if (issues.size() == 1) {
+			MessageIssue issue = issues.get(0);
+			errorObject.setMessage(issue.getText());
+			errorObject.setCode(issue.getIssueCode());
+			errorObject.setData(issue.getCause());
+		} else {
+			if (requestMessage.getMethod() != null)
+				errorObject.setMessage("Multiple issues were found in '" + requestMessage.getMethod() + "' request.");
+			else
+				errorObject.setMessage("Multiple issues were found in request.");
+			errorObject.setCode(ResponseErrorCode.InvalidRequest);
+			errorObject.setData(issues);
+		}
+		out.consume(createErrorResponseMessage(requestMessage, errorObject));
+	}
+	
+	protected void handleResponseIssues(ResponseMessage responseMessage, List<MessageIssue> issues) {
+		PendingRequestInfo requestInfo;
+		synchronized (sentRequestMap) {
+			requestInfo = sentRequestMap.remove(responseMessage.getId());
+		}
+		if (requestInfo == null) {
+			// We have no pending request information that matches the id given in the response
+			LOG.log(Level.WARNING, "Unmatched response message: " + responseMessage);
+			logIssues(responseMessage, issues);
+		} else {
+			requestInfo.future.completeExceptionally(new MessageIssueException(responseMessage, issues));
+		}
+	}
+
+	protected ResponseMessage createResponseMessage(RequestMessage requestMessage) {
+		ResponseMessage responseMessage = new ResponseMessage();
+		responseMessage.setRawId(requestMessage.getRawId());
+		responseMessage.setJsonrpc(MessageConstants.JSONRPC_VERSION);
+		return responseMessage;
+	}
+
+	protected ResponseMessage createResultResponseMessage(RequestMessage requestMessage, Object result) {
+		ResponseMessage responseMessage = createResponseMessage(requestMessage);
+		responseMessage.setResult(result);
+		return responseMessage;
+	}
+
+	protected ResponseMessage createErrorResponseMessage(RequestMessage requestMessage, ResponseError errorObject) {
+		ResponseMessage responseMessage = createResponseMessage(requestMessage);
+		responseMessage.setError(errorObject);
+		return responseMessage;
+	}
+
+	protected boolean isCancellation(Throwable t) {
+		if (t instanceof CompletionException) {
+			return isCancellation(t.getCause());
+		}
+		return (t instanceof CancellationException);
+	}
+
+	@Override
+	public String resolveMethod(String requestId) {
+		synchronized (sentRequestMap) {
+			PendingRequestInfo requestInfo = sentRequestMap.get(requestId);
+			if (requestInfo != null) {
+				return requestInfo.requestMessage.getMethod();
+			}
+		}
+		return null;
+	}
+	
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/ResponseErrorException.java b/java/org/eclipse/lsp4j/jsonrpc/ResponseErrorException.java
new file mode 100644
index 0000000..d700591
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/ResponseErrorException.java
@@ -0,0 +1,36 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc;
+
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseError;
+
+/**
+ * An exception thrown in order to send a response with an attached {@code error} object.
+ */
+public class ResponseErrorException extends RuntimeException {
+
+	private static final long serialVersionUID = -5970739895395246885L;
+	private ResponseError responseError;
+
+	public ResponseErrorException(ResponseError responseError) {
+		this.responseError = responseError;
+	}
+
+	@Override
+	public String getMessage() {
+		return responseError.getMessage();
+	}
+	
+	public ResponseError getResponseError() {
+		return responseError;
+	}
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/StandardLauncher.java b/java/org/eclipse/lsp4j/jsonrpc/StandardLauncher.java
new file mode 100644
index 0000000..0dd6b14
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/StandardLauncher.java
@@ -0,0 +1,55 @@
+/******************************************************************************
+ * Copyright (c) 2018 Red Hat Inc
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+
+import org.eclipse.lsp4j.jsonrpc.json.ConcurrentMessageProcessor;
+import org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer;
+
+public class StandardLauncher<T> implements Launcher<T> {
+	private final ExecutorService execService;
+	private final T remoteProxy;
+	private final RemoteEndpoint remoteEndpoint;
+	private final ConcurrentMessageProcessor msgProcessor;
+
+	public StandardLauncher(StreamMessageProducer reader, MessageConsumer messageConsumer,
+			ExecutorService execService, T remoteProxy, RemoteEndpoint remoteEndpoint) {
+		this(execService, remoteProxy, remoteEndpoint, 
+				new ConcurrentMessageProcessor(reader, messageConsumer));
+	}
+	
+	public StandardLauncher(
+			ExecutorService execService2, T remoteProxy2, RemoteEndpoint remoteEndpoint2,
+			ConcurrentMessageProcessor msgProcessor) {
+		this.execService = execService2;
+		this.remoteProxy = remoteProxy2;
+		this.remoteEndpoint = remoteEndpoint2;
+		this.msgProcessor = msgProcessor;
+	}
+
+	@Override
+	public Future<Void> startListening() {
+		return msgProcessor.beginProcessing(execService);
+	}
+
+	@Override
+	public T getRemoteProxy() {
+		return remoteProxy;
+	}
+
+	@Override
+	public RemoteEndpoint getRemoteEndpoint() {
+		return remoteEndpoint;
+	}
+}
\ No newline at end of file
diff --git a/java/org/eclipse/lsp4j/jsonrpc/TracingMessageConsumer.java b/java/org/eclipse/lsp4j/jsonrpc/TracingMessageConsumer.java
new file mode 100644
index 0000000..5730e11
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/TracingMessageConsumer.java
@@ -0,0 +1,219 @@
+/******************************************************************************
+ * Copyright (c) 2016-2019 TypeFox and others.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc;
+
+import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
+import org.eclipse.lsp4j.jsonrpc.json.StreamMessageConsumer;
+import org.eclipse.lsp4j.jsonrpc.messages.Message;
+import org.eclipse.lsp4j.jsonrpc.messages.NotificationMessage;
+import org.eclipse.lsp4j.jsonrpc.messages.RequestMessage;
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage;
+
+import java.io.PrintWriter;
+import java.time.Clock;
+import java.time.Instant;
+import java.time.format.DateTimeFormatter;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+import static java.util.logging.Level.WARNING;
+
+/**
+ * A {@link MessageConsumer} that outputs logs in a format that can be parsed by the LSP Inspector.
+ * https://microsoft.github.io/language-server-protocol/inspector/
+ */
+public class TracingMessageConsumer implements MessageConsumer {
+	private static final Logger LOG = Logger.getLogger(TracingMessageConsumer.class.getName());
+
+	private final MessageConsumer messageConsumer;
+	private final Map<String, RequestMetadata> sentRequests;
+	private final Map<String, RequestMetadata> receivedRequests;
+	private final PrintWriter printWriter;
+	private final Clock clock;
+	private final DateTimeFormatter dateTimeFormatter;
+
+	/**
+	 * @param messageConsumer The {@link MessageConsumer} to wrap.
+	 * @param sentRequests A map that keeps track of pending sent request data.
+	 * @param receivedRequests A map that keeps track of pending received request data.
+	 * @param printWriter Where to write the log to.
+	 * @param clock The clock that is used to calculate timestamps and durations.
+	 */
+	public TracingMessageConsumer(
+			MessageConsumer messageConsumer,
+			Map<String, RequestMetadata> sentRequests,
+			Map<String, RequestMetadata> receivedRequests,
+			PrintWriter printWriter,
+			Clock clock) {
+		this(messageConsumer, sentRequests, receivedRequests, printWriter, clock, null);
+	}
+
+	/**
+	 * @param messageConsumer The {@link MessageConsumer} to wrap.
+	 * @param sentRequests A map that keeps track of pending sent request data.
+	 * @param receivedRequests A map that keeps track of pending received request data.
+	 * @param printWriter Where to write the log to.
+	 * @param clock The clock that is used to calculate timestamps and durations.
+	 * @param locale THe Locale to format the timestamps and durations, or <code>null</code> to use default locale.
+	 */
+	public TracingMessageConsumer(
+			MessageConsumer messageConsumer,
+			Map<String, RequestMetadata> sentRequests,
+			Map<String, RequestMetadata> receivedRequests,
+			PrintWriter printWriter,
+			Clock clock,
+			Locale locale) {
+		this.messageConsumer = Objects.requireNonNull(messageConsumer);
+		this.sentRequests = Objects.requireNonNull(sentRequests);
+		this.receivedRequests = Objects.requireNonNull(receivedRequests);
+		this.printWriter = Objects.requireNonNull(printWriter);
+		this.clock = Objects.requireNonNull(clock);
+		if (locale == null) {
+			this.dateTimeFormatter = DateTimeFormatter.ofPattern("KK:mm:ss a").withZone(clock.getZone());
+		} else {
+			this.dateTimeFormatter = DateTimeFormatter.ofPattern("KK:mm:ss a", locale).withZone(clock.getZone());
+		}
+	}
+
+	/**
+	 * Constructs a log string for a given {@link Message}. The type of the {@link MessageConsumer}
+	 * determines if we're sending or receiving a message. The type of the @{link Message} determines
+	 * if it is a request, response, or notification.
+	 */
+	@Override
+	public void consume(Message message) throws MessageIssueException, JsonRpcException {
+		final Instant now = clock.instant();
+		final String date = dateTimeFormatter.format(now);
+		final String logString;
+
+		if (messageConsumer instanceof StreamMessageConsumer) {
+			logString = consumeMessageSending(message, now, date);
+		} else if (messageConsumer instanceof RemoteEndpoint) {
+			logString = consumeMessageReceiving(message, now, date);
+		} else {
+			LOG.log(WARNING, String.format("Unknown MessageConsumer type: %s", messageConsumer));
+			logString = null;
+		}
+
+		if (logString != null) {
+			printWriter.print(logString);
+			printWriter.flush();
+		}
+
+		messageConsumer.consume(message);
+	}
+
+	private String consumeMessageSending(Message message, Instant now, String date) {
+		if (message instanceof RequestMessage) {
+			RequestMessage requestMessage = (RequestMessage) message;
+			String id = requestMessage.getId();
+			String method = requestMessage.getMethod();
+			RequestMetadata requestMetadata = new RequestMetadata(method, now);
+			sentRequests.put(id, requestMetadata);
+			Object params = requestMessage.getParams();
+			String paramsJson = MessageJsonHandler.toString(params);
+			String format = "[Trace - %s] Sending request '%s - (%s)'\nParams: %s\n\n\n";
+			return String.format(format, date, method, id, paramsJson);
+		} else if (message instanceof ResponseMessage) {
+			ResponseMessage responseMessage = (ResponseMessage) message;
+			String id = responseMessage.getId();
+			RequestMetadata requestMetadata = receivedRequests.remove(id);
+			if (requestMetadata == null) {
+				LOG.log(WARNING, String.format("Unmatched response message: %s", message));
+				return null;
+			}
+			String method = requestMetadata.method;
+			long latencyMillis = now.toEpochMilli() - requestMetadata.start.toEpochMilli();
+			Object result = responseMessage.getResult();
+			String resultJson = MessageJsonHandler.toString(result);
+			String format =
+					"[Trace - %s] Sending response '%s - (%s)'. Processing request took %sms\nResult: %s\n\n\n";
+			return String.format(format, date, method, id, latencyMillis, resultJson);
+		} else if (message instanceof NotificationMessage) {
+			NotificationMessage notificationMessage = (NotificationMessage) message;
+			String method = notificationMessage.getMethod();
+			Object params = notificationMessage.getParams();
+			String paramsJson = MessageJsonHandler.toString(params);
+			String format = "[Trace - %s] Sending notification '%s'\nParams: %s\n\n\n";
+			return String.format(format, date, method, paramsJson);
+		} else {
+			LOG.log(WARNING, String.format("Unknown message type: %s", message));
+			return null;
+		}
+	}
+
+	private String consumeMessageReceiving(Message message, Instant now, String date) {
+		if (message instanceof RequestMessage) {
+			RequestMessage requestMessage = (RequestMessage) message;
+			String method = requestMessage.getMethod();
+			String id = requestMessage.getId();
+			RequestMetadata requestMetadata = new RequestMetadata(method, now);
+			receivedRequests.put(id, requestMetadata);
+			Object params = requestMessage.getParams();
+			String paramsJson = MessageJsonHandler.toString(params);
+			String format = "[Trace - %s] Received request '%s - (%s)'\nParams: %s\n\n\n";
+			return String.format(format, date, method, id, paramsJson);
+		} else if (message instanceof ResponseMessage) {
+			ResponseMessage responseMessage = (ResponseMessage) message;
+			String id = responseMessage.getId();
+			RequestMetadata requestMetadata = sentRequests.remove(id);
+			if (requestMetadata == null) {
+				LOG.log(WARNING, String.format("Unmatched response message: %s", message));
+				return null;
+			}
+			String method = requestMetadata.method;
+			long latencyMillis = now.toEpochMilli() - requestMetadata.start.toEpochMilli();
+			Object result = responseMessage.getResult();
+			String resultJson = MessageJsonHandler.toString(result);
+			Object error = responseMessage.getError();
+			String errorJson = MessageJsonHandler.toString(error);
+			String format = "[Trace - %s] Received response '%s - (%s)' in %sms\nResult: %s\nError: %s\n\n\n";
+			return String.format(format, date, method, id, latencyMillis, resultJson, errorJson);
+		} else if (message instanceof NotificationMessage) {
+			NotificationMessage notificationMessage = (NotificationMessage) message;
+			String method = notificationMessage.getMethod();
+			Object params = notificationMessage.getParams();
+			String paramsJson = MessageJsonHandler.toString(params);
+			String format = "[Trace - %s] Received notification '%s'\nParams: %s\n\n\n";
+			return String.format(format, date, method, paramsJson);
+		} else {
+			LOG.log(WARNING, String.format("Unknown message type: %s", message));
+			return null;
+		}
+	}
+
+	/** Data class for holding pending request metadata. */
+	public static class RequestMetadata {
+		final String method;
+		final Instant start;
+
+		public RequestMetadata(String method, Instant start) {
+			this.method = method;
+			this.start = start;
+		}
+
+		@Override
+		public boolean equals(Object o) {
+			if (this == o) return true;
+			if (o == null || getClass() != o.getClass()) return false;
+			RequestMetadata that = (RequestMetadata) o;
+			return Objects.equals(method, that.method) && Objects.equals(start, that.start);
+		}
+
+		@Override
+		public int hashCode() {
+			return Objects.hash(method, start);
+		}
+	}
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/debug/DebugLauncher.java b/java/org/eclipse/lsp4j/jsonrpc/debug/DebugLauncher.java
new file mode 100644
index 0000000..6c60a43
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/debug/DebugLauncher.java
@@ -0,0 +1,225 @@
+/******************************************************************************
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.debug;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import org.eclipse.lsp4j.jsonrpc.Endpoint;
+import org.eclipse.lsp4j.jsonrpc.Launcher;
+import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
+import org.eclipse.lsp4j.jsonrpc.RemoteEndpoint;
+import org.eclipse.lsp4j.jsonrpc.debug.json.DebugMessageJsonHandler;
+import org.eclipse.lsp4j.jsonrpc.json.JsonRpcMethod;
+import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
+import org.eclipse.lsp4j.jsonrpc.json.StreamMessageConsumer;
+import org.eclipse.lsp4j.jsonrpc.services.ServiceEndpoints;
+import org.eclipse.lsp4j.jsonrpc.validation.ReflectiveMessageValidator;
+
+import com.google.gson.GsonBuilder;
+
+/**
+ * This is the entry point for applications that use the debug protocol. A DebugLauncher does
+ * all the wiring that is necessary to connect your endpoint via an input stream
+ * and an output stream.
+ */
+public final class DebugLauncher {
+	
+	private DebugLauncher() {}
+
+	/**
+	 * Create a new Launcher for a given local service object, a given remote
+	 * interface and an input and output stream.
+	 *
+	 * @param localService
+	 *            - an object on which classes RPC methods are looked up
+	 * @param remoteInterface
+	 *            - an interface on which RPC methods are looked up
+	 * @param in
+	 *            - inputstream to listen for incoming messages
+	 * @param out
+	 *            - outputstream to send outgoing messages
+	 */
+	public static <T> Launcher<T> createLauncher(Object localService, Class<T> remoteInterface, InputStream in,
+			OutputStream out) {
+		return new Builder<T>()
+				.setLocalService(localService)
+				.setRemoteInterface(remoteInterface)
+				.setInput(in)
+				.setOutput(out)
+				.create();
+	}
+
+	/**
+	 * Create a new Launcher for a given local service object, a given remote
+	 * interface and an input and output stream, and set up message validation and
+	 * tracing.
+	 *
+	 * @param localService
+	 *            - an object on which classes RPC methods are looked up
+	 * @param remoteInterface
+	 *            - an interface on which RPC methods are looked up
+	 * @param in
+	 *            - inputstream to listen for incoming messages
+	 * @param out
+	 *            - outputstream to send outgoing messages
+	 * @param validate
+	 *            - whether messages should be validated with the
+	 *            {@link ReflectiveMessageValidator}
+	 * @param trace
+	 *            - a writer to which incoming and outgoing messages are traced, or
+	 *            {@code null} to disable tracing
+	 */
+	public static <T> Launcher<T> createLauncher(Object localService, Class<T> remoteInterface, InputStream in,
+			OutputStream out, boolean validate, PrintWriter trace) {
+		return new Builder<T>()
+				.setLocalService(localService)
+				.setRemoteInterface(remoteInterface)
+				.setInput(in)
+				.setOutput(out)
+				.validateMessages(validate)
+				.traceMessages(trace)
+				.create();
+	}
+
+	/**
+	 * Create a new Launcher for a given local service object, a given remote
+	 * interface and an input and output stream. Threads are started with the given
+	 * executor service. The wrapper function is applied to the incoming and
+	 * outgoing message streams so additional message handling such as validation
+	 * and tracing can be included.
+	 *
+	 * @param localService
+	 *            - an object on which classes RPC methods are looked up
+	 * @param remoteInterface
+	 *            - an interface on which RPC methods are looked up
+	 * @param in
+	 *            - inputstream to listen for incoming messages
+	 * @param out
+	 *            - outputstream to send outgoing messages
+	 * @param executorService
+	 *            - the executor service used to start threads
+	 * @param wrapper
+	 *            - a function for plugging in additional message consumers
+	 */
+	public static <T> Launcher<T> createLauncher(Object localService, Class<T> remoteInterface, InputStream in,
+			OutputStream out, ExecutorService executorService, Function<MessageConsumer, MessageConsumer> wrapper) {
+		return createIoLauncher(localService, remoteInterface, in, out, executorService, wrapper);
+	}
+
+	/**
+	 * Create a new Launcher for a given local service object, a given remote
+	 * interface and an input and output stream. Threads are started with the given
+	 * executor service. The wrapper function is applied to the incoming and
+	 * outgoing message streams so additional message handling such as validation
+	 * and tracing can be included.
+	 *
+	 * @param localService
+	 *            - an object on which classes RPC methods are looked up
+	 * @param remoteInterface
+	 *            - an interface on which RPC methods are looked up
+	 * @param in
+	 *            - inputstream to listen for incoming messages
+	 * @param out
+	 *            - outputstream to send outgoing messages
+	 * @param executorService
+	 *            - the executor service used to start threads
+	 * @param wrapper
+	 *            - a function for plugging in additional message consumers
+	 */
+	public static <T> Launcher<T> createIoLauncher(Object localService, Class<T> remoteInterface, InputStream in,
+			OutputStream out, ExecutorService executorService, Function<MessageConsumer, MessageConsumer> wrapper) {
+		return new Builder<T>()
+				.setLocalService(localService)
+				.setRemoteInterface(remoteInterface)
+				.setInput(in)
+				.setOutput(out)
+				.setExecutorService(executorService)
+				.wrapMessages(wrapper)
+				.create();
+	}
+
+	/**
+	 * Create a new Launcher for a given local service object, a given remote
+	 * interface and an input and output stream. Threads are started with the given
+	 * executor service. The wrapper function is applied to the incoming and
+	 * outgoing message streams so additional message handling such as validation
+	 * and tracing can be included. The {@code configureGson} function can be used
+	 * to register additional type adapters in the {@link GsonBuilder} in order to
+	 * support protocol classes that cannot be handled by Gson's reflective
+	 * capabilities.
+	 *
+	 * @param localService
+	 *            - an object on which classes RPC methods are looked up
+	 * @param remoteInterface
+	 *            - an interface on which RPC methods are looked up
+	 * @param in
+	 *            - inputstream to listen for incoming messages
+	 * @param out
+	 *            - outputstream to send outgoing messages
+	 * @param executorService
+	 *            - the executor service used to start threads
+	 * @param wrapper
+	 *            - a function for plugging in additional message consumers
+	 * @param configureGson
+	 *            - a function for Gson configuration
+	 */
+	public static <T> Launcher<T> createIoLauncher(Object localService, Class<T> remoteInterface, InputStream in,
+			OutputStream out, ExecutorService executorService, Function<MessageConsumer, MessageConsumer> wrapper,
+			Consumer<GsonBuilder> configureGson) {
+		return new Builder<T>()
+				.setLocalService(localService)
+				.setRemoteInterface(remoteInterface)
+				.setInput(in)
+				.setOutput(out)
+				.setExecutorService(executorService)
+				.wrapMessages(wrapper)
+				.configureGson(configureGson)
+				.create();
+	}
+	
+	/**
+	 * Launcher builder for the debug protocol. Adapts the JSON-RPC message classes to the JSON format used
+	 * by the debug protocol.
+	 */
+	public static class Builder<T> extends Launcher.Builder<T> {
+		
+		@Override
+		protected MessageJsonHandler createJsonHandler() {
+			Map<String, JsonRpcMethod> supportedMethods = getSupportedMethods();
+			if (configureGson != null)
+				return new DebugMessageJsonHandler(supportedMethods, configureGson);
+			else
+				return new DebugMessageJsonHandler(supportedMethods);
+		}
+		
+		@Override
+		protected RemoteEndpoint createRemoteEndpoint(MessageJsonHandler jsonHandler) {
+			MessageConsumer outgoingMessageStream = new StreamMessageConsumer(output, jsonHandler);
+			outgoingMessageStream = wrapMessageConsumer(outgoingMessageStream);
+			Endpoint localEndpoint = ServiceEndpoints.toEndpoint(localServices);
+			RemoteEndpoint remoteEndpoint;
+			if (exceptionHandler == null)
+				remoteEndpoint = new DebugRemoteEndpoint(outgoingMessageStream, localEndpoint);
+			else
+				remoteEndpoint = new DebugRemoteEndpoint(outgoingMessageStream, localEndpoint, exceptionHandler);
+			jsonHandler.setMethodProvider(remoteEndpoint);
+			return remoteEndpoint;
+		}
+		
+	}
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/debug/DebugRemoteEndpoint.java b/java/org/eclipse/lsp4j/jsonrpc/debug/DebugRemoteEndpoint.java
new file mode 100644
index 0000000..2290681
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/debug/DebugRemoteEndpoint.java
@@ -0,0 +1,64 @@
+/******************************************************************************
+ * Copyright (c) 2017 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.debug;
+
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Function;
+
+import org.eclipse.lsp4j.jsonrpc.Endpoint;
+import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
+import org.eclipse.lsp4j.jsonrpc.RemoteEndpoint;
+import org.eclipse.lsp4j.jsonrpc.debug.messages.DebugNotificationMessage;
+import org.eclipse.lsp4j.jsonrpc.debug.messages.DebugRequestMessage;
+import org.eclipse.lsp4j.jsonrpc.debug.messages.DebugResponseMessage;
+import org.eclipse.lsp4j.jsonrpc.messages.RequestMessage;
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseError;
+
+public class DebugRemoteEndpoint extends RemoteEndpoint {
+	private final AtomicInteger nextSeqId = new AtomicInteger();
+
+	public DebugRemoteEndpoint(MessageConsumer out, Endpoint localEndpoint) {
+		super(out, localEndpoint);
+	}
+
+	public DebugRemoteEndpoint(MessageConsumer out, Endpoint localEndpoint,
+			Function<Throwable, ResponseError> exceptionHandler) {
+		super(out, localEndpoint, exceptionHandler);
+	}
+
+	@Override
+	protected DebugRequestMessage createRequestMessage(String method, Object parameter) {
+		DebugRequestMessage requestMessage = new DebugRequestMessage();
+		requestMessage.setId(nextSeqId.incrementAndGet());
+		requestMessage.setMethod(method);
+		requestMessage.setParams(parameter);
+		return requestMessage;
+	}
+
+	@Override
+	protected DebugResponseMessage createResponseMessage(RequestMessage requestMessage) {
+		DebugResponseMessage responseMessage = new DebugResponseMessage();
+		responseMessage.setResponseId(nextSeqId.incrementAndGet());
+		responseMessage.setRawId(requestMessage.getRawId());
+		responseMessage.setMethod(requestMessage.getMethod());
+		return responseMessage;
+	}
+
+	@Override
+	protected DebugNotificationMessage createNotificationMessage(String method, Object parameter) {
+		DebugNotificationMessage notificationMessage = new DebugNotificationMessage();
+		notificationMessage.setId(nextSeqId.incrementAndGet());
+		notificationMessage.setMethod(method);
+		notificationMessage.setParams(parameter);
+		return notificationMessage;
+	}
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/debug/adapters/DebugEnumTypeAdapter.java b/java/org/eclipse/lsp4j/jsonrpc/debug/adapters/DebugEnumTypeAdapter.java
new file mode 100644
index 0000000..21977c0
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/debug/adapters/DebugEnumTypeAdapter.java
@@ -0,0 +1,92 @@
+/******************************************************************************
+ * Copyright (c) 2017 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.debug.adapters;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.google.gson.Gson;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.annotations.SerializedName;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.JsonWriter;
+
+public class DebugEnumTypeAdapter<T extends Enum<T>> extends TypeAdapter<T> {
+	public static class Factory implements TypeAdapterFactory {
+		@Override
+		@SuppressWarnings({ "unchecked", "rawtypes" })
+		public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
+			Class<?> rawType = typeToken.getRawType();
+			if (!Enum.class.isAssignableFrom(rawType) || rawType == Enum.class)
+				return null;
+			if (!rawType.isEnum())
+				rawType = rawType.getSuperclass();
+			return new DebugEnumTypeAdapter(rawType);
+		}
+
+	}
+
+	private final Map<String, T> serializedFormToEnum = new HashMap<String, T>();
+	private final Map<T, String> enumToSerializedForm = new HashMap<T, String>();
+
+	public DebugEnumTypeAdapter(Class<T> clazz) {
+		try {
+			for (T constant : clazz.getEnumConstants()) {
+				String name = constant.name();
+				String serializedForm = getSerializedForm(name);
+				// Like default gson, allow overriding names with SerializedName
+				SerializedName annotation = clazz.getField(name).getAnnotation(SerializedName.class);
+				if (annotation != null) {
+					serializedForm = annotation.value();
+					for (String alternate : annotation.alternate()) {
+						serializedFormToEnum.put(alternate, constant);
+					}
+				}
+				serializedFormToEnum.put(serializedForm, constant);
+				enumToSerializedForm.put(constant, serializedForm);
+			}
+		} catch (NoSuchFieldException e) {
+			throw new AssertionError(e);
+		}
+	}
+
+	private String getSerializedForm(String name) {
+		name = name.toLowerCase();
+		Matcher m = Pattern.compile("_[a-z]").matcher(name);
+		StringBuffer sb = new StringBuffer();
+		while (m.find()) {
+			m.appendReplacement(sb, m.group().toUpperCase());
+		}
+		m.appendTail(sb);
+		return sb.toString().replaceAll("_", "");
+	}
+
+	@Override
+	public T read(JsonReader in) throws IOException {
+		if (in.peek() == JsonToken.NULL) {
+			in.nextNull();
+			return null;
+		}
+		return serializedFormToEnum.get(in.nextString());
+	}
+
+	@Override
+	public void write(JsonWriter out, T value) throws IOException {
+		out.value(value == null ? null : enumToSerializedForm.get(value));
+	}
+}
\ No newline at end of file
diff --git a/java/org/eclipse/lsp4j/jsonrpc/debug/adapters/DebugMessageTypeAdapter.java b/java/org/eclipse/lsp4j/jsonrpc/debug/adapters/DebugMessageTypeAdapter.java
new file mode 100644
index 0000000..960bacf
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/debug/adapters/DebugMessageTypeAdapter.java
@@ -0,0 +1,483 @@
+/******************************************************************************
+ * Copyright (c) 2017 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.debug.adapters;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.lang.reflect.Type;
+
+import org.eclipse.lsp4j.jsonrpc.MessageIssueException;
+import org.eclipse.lsp4j.jsonrpc.debug.messages.DebugNotificationMessage;
+import org.eclipse.lsp4j.jsonrpc.debug.messages.DebugRequestMessage;
+import org.eclipse.lsp4j.jsonrpc.debug.messages.DebugResponseMessage;
+import org.eclipse.lsp4j.jsonrpc.json.JsonRpcMethod;
+import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
+import org.eclipse.lsp4j.jsonrpc.json.MethodProvider;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.MessageTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.messages.Message;
+import org.eclipse.lsp4j.jsonrpc.messages.MessageIssue;
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseError;
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseErrorCode;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParseException;
+import com.google.gson.JsonParser;
+import com.google.gson.JsonSyntaxException;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.JsonWriter;
+import com.google.gson.stream.MalformedJsonException;
+
+/**
+ * The {@link DebugMessageTypeAdapter} provides an adapter that maps Debug
+ * Server Protocol style JSON to/from LSP4J's JSONRPC implementation. The Debug
+ * Server Protocol (DSP) has its own message format that is quite similar to
+ * JSON-RPC 2.0. The DSP is defined in a <a href=
+ * "https://github.com/Microsoft/vscode-debugadapter-node/blob/master/debugProtocol.json">JSON
+ * schema in the VS Code Debug Adapter</a>. This section documents how LSP4J's
+ * jsonrpc classes maps to the Debug Protocol, using some extensions in the DSP
+ * code to the lsp4j's {@link Message}s.
+ * <p>
+ *
+ * <pre>
+	"ProtocolMessage": { // implemented by {@link Message}
+		"type": "object",
+		"description": "Base class of requests, responses, and events.",
+		"properties": {
+			"seq": { // implemented by (depending on type, with conversion to/from String):
+			         //  {@link DebugRequestMessage#getId()}, or
+			         //  {@link DebugNotificationMessage#getId()} or
+			         //  {@link DebugResponseMessage#getResponseId()}
+				"type": "integer",
+				"description": "Sequence number."
+			},
+			"type": { // implicit in type of subclass of {@link Message}
+				"type": "string",
+				"description": "Message type.",
+				"_enum": [ "request", "response", "event" ]
+			}
+		},
+		"required": [ "seq", "type" ]
+	},
+
+	"Request": { // implemented by {@link DebugRequestMessage}
+		"allOf": [ { "$ref": "#/definitions/ProtocolMessage" }, {
+			"type": "object",
+			"description": "A client or server-initiated request.",
+			"properties": {
+				"type": { // implicit by being of type {@link DebugRequestMessage}
+					"type": "string",
+					"enum": [ "request" ]
+				},
+				"command": { // implemented by {@link DebugRequestMessage#getMethod()}
+					"type": "string",
+					"description": "The command to execute."
+				},
+				"arguments": { // implemented by {@link DebugRequestMessage#getParams()}
+					"type": [ "array", "boolean", "integer", "null", "number" , "object", "string" ],
+					"description": "Object containing arguments for the command."
+				}
+			},
+			"required": [ "type", "command" ]
+		}]
+	},
+
+	"Event": { // implemented by {@link DebugNotificationMessage}
+		"allOf": [ { "$ref": "#/definitions/ProtocolMessage" }, {
+			"type": "object",
+			"description": "Server-initiated event.",
+			"properties": {
+				"type": { // implicit by being of type {@link DebugNotificationMessage}
+					"type": "string",
+					"enum": [ "event" ]
+				},
+				"event": { // implemented by {@link DebugNotificationMessage#getMethod()}
+					"type": "string",
+					"description": "Type of event."
+				},
+				"body": { // implemented by {@link DebugNotificationMessage#getParams()}
+					"type": [ "array", "boolean", "integer", "null", "number" , "object", "string" ],
+					"description": "Event-specific information."
+				}
+			},
+			"required": [ "type", "event" ]
+		}]
+	},
+
+	"Response": { // implemented by {@link DebugResponseMessage}
+		"allOf": [ { "$ref": "#/definitions/ProtocolMessage" }, {
+			"type": "object",
+			"description": "Response to a request.",
+			"properties": {
+				"type": { // implicit by being of type {@link DebugResponseMessage}
+					"type": "string",
+					"enum": [ "response" ]
+				},
+				"request_seq": { // implemented by {@link DebugResponseMessage#getId()}
+					"type": "integer",
+					"description": "Sequence number of the corresponding request."
+				},
+				"success": { // implemented by {@link DebugResponseMessage#getError()} == null
+					"type": "boolean",
+					"description": "Outcome of the request."
+				},
+				"command": { // implemented by {@link DebugResponseMessage#getMethod()}
+					"type": "string",
+					"description": "The command requested."
+				},
+				"message": { // implemented by {@link ResponseError#getMessage()}
+					"type": "string",
+					"description": "Contains error message if success == false."
+				},
+				"body": { // implemented by {@link DebugResponseMessage#getResult()} for success and {@link ResponseError#getData()} for error
+					"type": [ "array", "boolean", "integer", "null", "number" , "object", "string" ],
+					"description": "Contains request result if success is true and optional error details if success is false."
+				}
+			},
+			"required": [ "type", "request_seq", "success", "command" ]
+		}]
+	},
+ * </pre>
+ *
+ */
+public class DebugMessageTypeAdapter extends MessageTypeAdapter {
+
+	public static class Factory implements TypeAdapterFactory {
+
+		private final MessageJsonHandler handler;
+
+		public Factory(MessageJsonHandler handler) {
+			this.handler = handler;
+		}
+
+		@Override
+		@SuppressWarnings("unchecked")
+		public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
+			if (!Message.class.isAssignableFrom(typeToken.getRawType()))
+				return null;
+			return (TypeAdapter<T>) new DebugMessageTypeAdapter(handler, gson);
+		}
+
+	}
+
+	private final MessageJsonHandler handler;
+	private final Gson gson;
+
+	public DebugMessageTypeAdapter(MessageJsonHandler handler, Gson gson) {
+		super(handler, gson);
+		this.handler = handler;
+		this.gson = gson;
+	}
+
+	@Override
+	public Message read(JsonReader in) throws IOException {
+		if (in.peek() == JsonToken.NULL) {
+			in.nextNull();
+			return null;
+		}
+
+		in.beginObject();
+		String messageType = null, method = null, message = null;
+		int seq = 0, request_seq = 0;
+		Boolean rawSuccess = null;
+		Object rawParams = null;
+		Object rawBody = null;
+
+		try {
+
+			while (in.hasNext()) {
+				String name = in.nextName();
+				switch (name) {
+				case "seq": {
+					seq = in.nextInt();
+					break;
+				}
+				case "request_seq": {
+					// on responses we treat the request_seq as the id
+					request_seq = in.nextInt();
+					break;
+				}
+				case "type": {
+					messageType = in.nextString();
+					break;
+				}
+				case "success": {
+					rawSuccess = in.nextBoolean();
+					break;
+				}
+				case "command": {
+					method = in.nextString();
+					break;
+				}
+				case "event": {
+					method = in.nextString();
+					break;
+				}
+				case "message": {
+					if (in.peek() == JsonToken.NULL) {
+						in.nextNull();
+					} else {
+						message = in.nextString();
+					}
+					break;
+				}
+				case "arguments": {
+					rawParams = parseParams(in, method);
+					break;
+				}
+				case "body": {
+					rawBody = parseBody(in, messageType, request_seq, method, rawSuccess);
+					break;
+				}
+				default:
+					in.skipValue();
+				}
+			}
+			boolean success = rawSuccess != null ? rawSuccess : false;
+			Object params = parseParams(rawParams, method);
+			Object body = parseBody(rawBody, messageType, request_seq, method, success);
+
+			in.endObject();
+			return createMessage(messageType, seq, request_seq, method, success, message, params, body);
+
+		} catch (JsonSyntaxException | MalformedJsonException | EOFException exception) {
+			if ("request".equals(messageType) || "event".equals(messageType) || "response".equals(messageType)) {
+				// Create a message and bundle it to an exception with an issue that wraps the original exception
+				boolean success = rawSuccess != null ? rawSuccess : false;
+				Message resultMessage = createMessage(messageType, seq, request_seq, method, success, message, rawParams, rawBody);
+				MessageIssue issue = new MessageIssue("Message could not be parsed.", ResponseErrorCode.ParseError.getValue(), exception);
+				throw new MessageIssueException(resultMessage, issue);
+			} else {
+				throw exception;
+			}
+		}
+	}
+
+	/**
+	 * Convert the json input into the body object corresponding to the type of
+	 * message.
+	 *
+	 * If the type of message or any other necessary field is not known until after
+	 * parsing, call {@link #parseBody(Object, String, int, String, Boolean)} on
+	 * the return value of this call for a second chance conversion.
+	 *
+	 * @param in
+	 *            json input to read from
+	 * @param messageType
+	 *            message type if known
+	 * @param request_seq
+	 *            seq id of request message if known
+	 * @param method
+	 *            event/method being called
+	 * @param success
+	 *            if success of a response is known
+	 * @return correctly typed object if the correct expected type can be
+	 *         determined, or a JsonElement representing the body
+	 */
+	protected Object parseBody(JsonReader in, String messageType, int request_seq, String method, Boolean success)
+			throws IOException {
+		if ("event".equals(messageType)) {
+			return parseParams(in, method);
+		} else if ("response".equals(messageType) && success != null && success) {
+			return super.parseResult(in, Integer.toString(request_seq));
+		} else {
+			return JsonParser.parseReader(in);
+		}
+	}
+
+	/**
+	 * Convert the JsonElement into the body object corresponding to the type of
+	 * message. If the rawBody is already converted, does nothing.
+	 *
+	 * @param rawBody
+	 *            json element to read from
+	 * @param messageType
+	 *            message type if known
+	 * @param request_seq
+	 *            seq id of request message if known
+	 * @param method
+	 *            event/method being called
+	 * @param success
+	 *            if success of a response is known
+	 * @return correctly typed object if the correct expected type can be
+	 *         determined, or rawBody unmodified if no conversion can be done.
+	 */
+	protected Object parseBody(Object rawBody, String messageType, int request_seq, String method, Boolean success) {
+		if ("event".equals(messageType)) {
+			return parseParams(rawBody, method);
+		} else if ("response".equals(messageType)) {
+			if (success != null && success) {
+				return super.parseResult(rawBody, Integer.toString(request_seq));
+			}
+			if (isNull(rawBody)) {
+				return null;
+			}
+			if (!(rawBody instanceof JsonElement)) {
+				return rawBody;
+			}
+			JsonElement rawJsonParams = (JsonElement) rawBody;
+			return fromJson(rawJsonParams, Object.class);
+		}
+		return rawBody;
+	}
+
+	private Message createMessage(String messageType, int seq, int request_seq, String method, boolean success,
+			String errorMessage, Object params, Object body) throws JsonParseException {
+		if (messageType == null) {
+			throw new JsonParseException("Unable to identify the input message. Missing 'type' field.");
+		}
+		switch (messageType) {
+		case "request": {
+			DebugRequestMessage message = new DebugRequestMessage();
+			message.setId(seq);
+			message.setMethod(method);
+			message.setParams(params);
+			return message;
+		}
+		case "event": {
+			DebugNotificationMessage message = new DebugNotificationMessage();
+			message.setId(seq);
+			message.setMethod(method);
+			message.setParams(body);
+			return message;
+		}
+		case "response": {
+			DebugResponseMessage message = new DebugResponseMessage();
+			message.setId(request_seq);
+			message.setResponseId(seq);
+			message.setMethod(method);
+			if (!success) {
+				ResponseError error = new ResponseError();
+				error.setCode(ResponseErrorCode.UnknownErrorCode);
+				error.setData(body);
+				if (errorMessage == null) {
+					// Some debug servers/clients don't provide a "message" field on an error.
+					// Generally in those cases the body has some extra details to figure out
+					// what went wrong.
+					errorMessage = "Unset error message.";
+				}
+				error.setMessage(errorMessage);
+				message.setError(error);
+			} else {
+				if (body instanceof JsonElement) {
+					// Type of result could not be resolved - try again with the parsed JSON tree
+					MethodProvider methodProvider = handler.getMethodProvider();
+					if (methodProvider != null) {
+						String resolvedMethod = methodProvider.resolveMethod(Integer.toString(request_seq));
+						if (resolvedMethod != null) {
+							JsonRpcMethod jsonRpcMethod = handler.getJsonRpcMethod(resolvedMethod);
+							if (jsonRpcMethod != null) {
+								TypeAdapter<?> typeAdapter = null;
+								Type returnType = jsonRpcMethod.getReturnType();
+								if (jsonRpcMethod.getReturnTypeAdapterFactory() != null)
+									typeAdapter = jsonRpcMethod.getReturnTypeAdapterFactory().create(gson, TypeToken.get(returnType));
+								JsonElement jsonElement = (JsonElement) body;
+								if (typeAdapter != null)
+									body = typeAdapter.fromJsonTree(jsonElement);
+								else
+									body = gson.fromJson(jsonElement, returnType);
+							}
+						}
+					}
+				}
+				message.setResult(body);
+			}
+			return message;
+		}
+		default:
+			throw new JsonParseException("Unable to identify the input message.");
+		}
+	}
+
+	@Override
+	public void write(JsonWriter out, Message message) throws IOException {
+		out.beginObject();
+		if (message instanceof DebugRequestMessage) {
+			DebugRequestMessage requestMessage = (DebugRequestMessage) message;
+			out.name("type");
+			out.value("request");
+			out.name("seq");
+			writeIntId(out, requestMessage.getRawId());
+			out.name("command");
+			out.value(requestMessage.getMethod());
+			Object params = requestMessage.getParams();
+			if (params != null) {
+				out.name("arguments");		
+				gson.toJson(params, params.getClass(), out);
+			}
+		} else if (message instanceof DebugResponseMessage) {
+			DebugResponseMessage responseMessage = (DebugResponseMessage) message;
+			out.name("type");
+			out.value("response");
+			out.name("seq");
+			writeIntId(out, responseMessage.getRawResponseId());
+			out.name("request_seq");
+			writeIntId(out, responseMessage.getRawId());
+			out.name("command");
+			out.value(responseMessage.getMethod());
+			ResponseError error = responseMessage.getError();
+			if (error != null) {
+				out.name("success");
+				out.value(false);
+				String errorMessage = error.getMessage();
+				out.name("message");
+				if (errorMessage == null)
+					writeNullValue(out);
+				else
+					gson.toJson(errorMessage, errorMessage.getClass(), out);
+
+				Object errorData = error.getData();
+				if (errorData != null) {
+					out.name("body");
+					gson.toJson(errorData, errorData.getClass(), out);
+				}
+			} else {
+				out.name("success");
+				out.value(true);
+				Object result = responseMessage.getResult();
+				if (result != null) {
+					out.name("body");
+					gson.toJson(result, result.getClass(), out);
+				}
+			}
+		} else if (message instanceof DebugNotificationMessage) {
+			DebugNotificationMessage notificationMessage = (DebugNotificationMessage) message;
+			out.name("type");
+			out.value("event");
+			out.name("seq");
+			writeIntId(out, notificationMessage.getRawId());
+			out.name("event");
+			out.value(notificationMessage.getMethod());
+			Object params = notificationMessage.getParams();
+			if (params != null) {
+				out.name("body");
+				gson.toJson(params, params.getClass(), out);
+			}
+		}
+
+		out.endObject();
+	}
+
+	private void writeIntId(JsonWriter out, Either<String, Number> id) throws IOException {
+		if (id == null)
+			writeNullValue(out);
+		else if (id.isLeft())
+			out.value(Integer.parseInt(id.getLeft()));
+		else if (id.isRight())
+			out.value(id.getRight());
+	}
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/debug/json/DebugMessageJsonHandler.java b/java/org/eclipse/lsp4j/jsonrpc/debug/json/DebugMessageJsonHandler.java
new file mode 100644
index 0000000..1e72557
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/debug/json/DebugMessageJsonHandler.java
@@ -0,0 +1,38 @@
+/******************************************************************************

+ * Copyright (c) 2017 Kichwa Coders Ltd. and others.

+ * 

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v. 2.0 which is available at

+ * http://www.eclipse.org/legal/epl-2.0,

+ * or the Eclipse Distribution License v. 1.0 which is available at

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ * 

+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause

+ ******************************************************************************/

+package org.eclipse.lsp4j.jsonrpc.debug.json;

+

+import java.util.Map;

+import java.util.function.Consumer;

+

+import org.eclipse.lsp4j.jsonrpc.debug.adapters.DebugEnumTypeAdapter;

+import org.eclipse.lsp4j.jsonrpc.debug.adapters.DebugMessageTypeAdapter;

+import org.eclipse.lsp4j.jsonrpc.json.JsonRpcMethod;

+import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;

+

+import com.google.gson.GsonBuilder;

+

+public class DebugMessageJsonHandler extends MessageJsonHandler {

+	public DebugMessageJsonHandler(Map<String, JsonRpcMethod> supportedMethods) {

+		super(supportedMethods);

+	}

+

+	public DebugMessageJsonHandler(Map<String, JsonRpcMethod> supportedMethods, Consumer<GsonBuilder> configureGson) {

+		super(supportedMethods, configureGson);

+	}

+

+	public GsonBuilder getDefaultGsonBuilder() {

+		return super.getDefaultGsonBuilder().registerTypeAdapterFactory(new DebugMessageTypeAdapter.Factory(this))

+				.registerTypeAdapterFactory(new DebugEnumTypeAdapter.Factory());

+	}

+

+}

diff --git a/java/org/eclipse/lsp4j/jsonrpc/debug/messages/DebugNotificationMessage.java b/java/org/eclipse/lsp4j/jsonrpc/debug/messages/DebugNotificationMessage.java
new file mode 100644
index 0000000..738a789
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/debug/messages/DebugNotificationMessage.java
@@ -0,0 +1,86 @@
+/******************************************************************************
+ * Copyright (c) 2017 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.debug.messages;
+
+import org.eclipse.lsp4j.jsonrpc.debug.adapters.DebugMessageTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.messages.NotificationMessage;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+
+/**
+ * DSP specific version of NotificationMessage.
+ *
+ * @see DebugMessageTypeAdapter
+ */
+public class DebugNotificationMessage extends NotificationMessage {
+
+	/**
+	 * The notification id.
+	 */
+	@NonNull
+	private Either<String, Number> id;
+
+	public String getId() {
+		if (id == null)
+			return null;
+		if (id.isLeft())
+			return id.getLeft();
+		if (id.isRight())
+			return id.getRight().toString();
+		return null;
+	}
+	
+	@NonNull
+	public Either<String, Number> getRawId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = Either.forLeft(id);
+	}
+	
+	public void setId(int id) {
+		this.id = Either.forRight(id);
+	}
+	
+	public void setRawId(@NonNull Either<String, Number> id) {
+		this.id = id;
+	}
+
+	@Override
+	public boolean equals(final Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		if (!super.equals(obj))
+			return false;
+		DebugNotificationMessage other = (DebugNotificationMessage) obj;
+		if (this.id == null) {
+			if (other.id != null)
+				return false;
+		} else if (!this.id.equals(other.id))
+			return false;
+		return true;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = super.hashCode();
+		result = prime * result + ((this.id == null) ? 0 : this.id.hashCode());
+		return result;
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/debug/messages/DebugRequestMessage.java b/java/org/eclipse/lsp4j/jsonrpc/debug/messages/DebugRequestMessage.java
new file mode 100644
index 0000000..dca7310
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/debug/messages/DebugRequestMessage.java
@@ -0,0 +1,24 @@
+/******************************************************************************
+ * Copyright (c) 2017 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.debug.messages;
+
+import org.eclipse.lsp4j.jsonrpc.debug.adapters.DebugMessageTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.messages.RequestMessage;
+
+/**
+ * DSP specific version of RequestMessage.
+ *
+ * @see DebugMessageTypeAdapter
+ */
+public class DebugRequestMessage extends RequestMessage {
+	// no additional fields are needed to represent request messages in DSP
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/debug/messages/DebugResponseMessage.java b/java/org/eclipse/lsp4j/jsonrpc/debug/messages/DebugResponseMessage.java
new file mode 100644
index 0000000..26fe32b
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/debug/messages/DebugResponseMessage.java
@@ -0,0 +1,109 @@
+/******************************************************************************
+ * Copyright (c) 2017 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.debug.messages;
+
+import org.eclipse.lsp4j.jsonrpc.debug.adapters.DebugMessageTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+
+/**
+ * DSP specific version of ResponseMessage.
+ *
+ * @see DebugMessageTypeAdapter
+ */
+public class DebugResponseMessage extends ResponseMessage {
+
+	/**
+	 * The response id.
+	 *
+	 * The {@link #getId()} field is the id of the message being replied to.
+	 */
+	@NonNull
+	private Either<String, Number> responseId;
+
+	public String getResponseId() {
+		if (responseId == null)
+			return null;
+		if (responseId.isLeft())
+			return responseId.getLeft();
+		if (responseId.isRight())
+			return responseId.getRight().toString();
+		return null;
+	}
+	
+	@NonNull
+	public Either<String, Number> getRawResponseId() {
+		return responseId;
+	}
+
+	public void setResponseId(String id) {
+		this.responseId = Either.forLeft(id);
+	}
+	
+	public void setResponseId(int id) {
+		this.responseId = Either.forRight(id);
+	}
+	
+	public void setRawResponseId(@NonNull Either<String, Number> id) {
+		this.responseId = id;
+	}
+
+	/**
+	 * The method that was invoked.
+	 */
+	@NonNull
+	private String method;
+
+	@NonNull
+	public String getMethod() {
+		return this.method;
+	}
+
+	public void setMethod(@NonNull String method) {
+		this.method = method;
+	}
+
+	@Override
+	public boolean equals(final Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		if (!super.equals(obj))
+			return false;
+		DebugResponseMessage other = (DebugResponseMessage) obj;
+		if (this.responseId == null) {
+			if (other.responseId != null)
+				return false;
+		} else if (!this.responseId.equals(other.responseId))
+			return false;
+		if (this.method == null) {
+			if (other.method != null)
+				return false;
+		} else if (!this.method.equals(other.method))
+			return false;
+		return true;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = super.hashCode();
+		result = prime * result + ((this.responseId == null) ? 0 : this.responseId.hashCode());
+		result = prime * result + ((this.method == null) ? 0 : this.method.hashCode());
+		return result;
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/json/ConcurrentMessageProcessor.java b/java/org/eclipse/lsp4j/jsonrpc/json/ConcurrentMessageProcessor.java
new file mode 100644
index 0000000..1eedf2e
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/json/ConcurrentMessageProcessor.java
@@ -0,0 +1,131 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.json;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
+import org.eclipse.lsp4j.jsonrpc.MessageProducer;
+
+/**
+ * This class connects a message producer with a message consumer by listening for new messages in a dedicated thread.
+ */
+public class ConcurrentMessageProcessor implements Runnable {
+	
+	/**
+	 * Start a thread that listens for messages in the message producer and forwards them to the message consumer.
+	 * 
+	 * @param messageProducer - produces messages, e.g. by reading from an input channel
+	 * @param messageConsumer - processes messages and potentially forwards them to other consumers
+	 * @param executorService - the thread is started using this service
+	 * @return a future that is resolved when the started thread is terminated, e.g. by closing a stream
+	 * @deprecated Please use the non-static ConcurrentMessageProcessor.beginProcessing() instead.
+	 */
+	@Deprecated
+	public static Future<Void> startProcessing(MessageProducer messageProducer, MessageConsumer messageConsumer,
+			ExecutorService executorService) {
+		ConcurrentMessageProcessor reader = new ConcurrentMessageProcessor(messageProducer, messageConsumer);
+		final Future<?> result = executorService.submit(reader);
+		return wrapFuture(result, messageProducer);
+	}
+
+	public static Future<Void> wrapFuture(Future<?> result, MessageProducer messageProducer) {
+		return new Future<Void>() {
+
+			@Override
+			public Void get() throws InterruptedException, ExecutionException {
+				return (Void) result.get();
+			}
+
+			@Override
+			public Void get(long timeout, TimeUnit unit)
+					throws InterruptedException, ExecutionException, TimeoutException {
+				return (Void) result.get(timeout, unit);
+			}
+
+			@Override
+			public boolean isDone() {
+				return result.isDone();
+			}
+
+			@Override
+			public boolean cancel(boolean mayInterruptIfRunning) {
+				if (mayInterruptIfRunning && messageProducer instanceof Closeable) {
+					try {
+						((Closeable) messageProducer).close();
+					} catch (IOException e) {
+						throw new RuntimeException(e);
+					}
+				}
+				return result.cancel(mayInterruptIfRunning);
+			}
+
+			@Override
+			public boolean isCancelled() {
+				return result.isCancelled();
+			}
+		};
+	}
+
+	private static final Logger LOG = Logger.getLogger(ConcurrentMessageProcessor.class.getName());
+
+	private boolean isRunning;
+
+	private final MessageProducer messageProducer;
+	private final MessageConsumer messageConsumer;
+
+	public ConcurrentMessageProcessor(MessageProducer messageProducer, MessageConsumer messageConsumer) {
+		this.messageProducer = messageProducer;
+		this.messageConsumer = messageConsumer;
+	}
+	
+	/**
+	 * Start a thread that listens for messages in the message producer and forwards them to the message consumer.
+	 * 
+	 * @param executorService - the thread is started using this service
+	 * @return a future that is resolved when the started thread is terminated, e.g. by closing a stream
+	 */
+	public Future<Void> beginProcessing(ExecutorService executorService) {
+		final Future<?> result = executorService.submit(this);
+		return wrapFuture(result, messageProducer);
+	}
+
+	public void run() {
+		processingStarted();
+		try {
+			messageProducer.listen(messageConsumer);
+		} catch (Exception e) {
+			LOG.log(Level.SEVERE, e.getMessage(), e);
+		} finally {
+			processingEnded();
+		}
+	}
+
+	protected void processingStarted() {
+		if (isRunning) {
+			throw new IllegalStateException("The message processor is already running.");
+		}
+		isRunning = true;
+	}
+
+	protected void processingEnded() {
+		isRunning = false;
+	}
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/json/JsonRpcMethod.java b/java/org/eclipse/lsp4j/jsonrpc/json/JsonRpcMethod.java
new file mode 100644
index 0000000..b2dcf13
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/json/JsonRpcMethod.java
@@ -0,0 +1,88 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.json;
+
+import java.lang.reflect.Type;
+
+import com.google.gson.TypeAdapterFactory;
+
+/**
+ * A description of a JSON-RPC method. 
+ */
+public class JsonRpcMethod {
+	
+	private final String methodName;
+	private final Type[] parameterTypes;
+	private final Type returnType;
+	private final TypeAdapterFactory returnTypeAdapterFactory;
+	private final boolean isNotification;
+	
+	private JsonRpcMethod(String methodName, Type[] parameterTypes, Type returnType, TypeAdapterFactory returnTypeAdapterFactory,
+			boolean isNotification) {
+		if (methodName == null)
+			throw new NullPointerException("methodName");
+		this.methodName = methodName;
+		this.parameterTypes = parameterTypes;
+		this.returnType = returnType;
+		this.returnTypeAdapterFactory = returnTypeAdapterFactory;
+		this.isNotification = isNotification;
+	}
+
+	public String getMethodName() {
+		return methodName;
+	}
+	
+	public Type[] getParameterTypes() {
+		return parameterTypes;
+	}
+	
+	public Type getReturnType() {
+		return returnType;
+	}
+	
+	public TypeAdapterFactory getReturnTypeAdapterFactory() {
+		return returnTypeAdapterFactory;
+	}
+	
+	public boolean isNotification() {
+		return isNotification;
+	}
+	
+	public static JsonRpcMethod notification(String name, Type... parameterTypes) {
+		return new JsonRpcMethod(name, parameterTypes, Void.class, null, true);
+	}
+	
+	public static JsonRpcMethod request(String name, Type returnType, Type... parameterTypes) {
+		return new JsonRpcMethod(name, parameterTypes, returnType, null, false);
+	}
+	
+	public static JsonRpcMethod request(String name, Type returnType, TypeAdapterFactory returnTypeAdapterFactory, Type... parameterTypes) {
+		return new JsonRpcMethod(name, parameterTypes, returnType, returnTypeAdapterFactory, false);
+	}
+	
+	@Override
+	public String toString() {
+		StringBuilder builder = new StringBuilder();
+		if (isNotification)
+			builder.append("JsonRpcMethod (notification) {\n");
+		else
+			builder.append("JsonRpcMethod (request) {\n");
+		builder.append("\tmethodName: ").append(methodName).append('\n');
+		if (parameterTypes != null)
+			builder.append("\tparameterTypes: ").append(parameterTypes).append('\n');
+		if (returnType != null)
+			builder.append("\treturnType: ").append(returnType).append('\n');
+		builder.append("}");
+		return builder.toString();
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/json/JsonRpcMethodProvider.java b/java/org/eclipse/lsp4j/jsonrpc/json/JsonRpcMethodProvider.java
new file mode 100644
index 0000000..a731200
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/json/JsonRpcMethodProvider.java
@@ -0,0 +1,26 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.json;
+
+import java.util.Map;
+
+import org.eclipse.lsp4j.jsonrpc.Endpoint;
+
+/**
+ * Provides {@link JsonRpcMethod}. Can be implemented by {@link Endpoint}s to
+ * provide information about the supported methods.
+ */
+public interface JsonRpcMethodProvider {
+
+	Map<String, JsonRpcMethod> supportedMethods();
+	
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/json/MessageConstants.java b/java/org/eclipse/lsp4j/jsonrpc/json/MessageConstants.java
new file mode 100644
index 0000000..e6676fa
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/json/MessageConstants.java
@@ -0,0 +1,22 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.json;
+
+public interface MessageConstants {
+	
+	public static String JSONRPC_VERSION = "2.0";
+	public static String CONTENT_LENGTH_HEADER = "Content-Length";
+	public static String CONTENT_TYPE_HEADER = "Content-Type";
+	public static String JSON_MIME_TYPE = "application/json";
+	public static String CRLF = "\r\n";
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/json/MessageJsonHandler.java b/java/org/eclipse/lsp4j/jsonrpc/json/MessageJsonHandler.java
new file mode 100644
index 0000000..f7584c8
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/json/MessageJsonHandler.java
@@ -0,0 +1,164 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.json;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Collections;
+import java.util.Map;
+import java.util.function.Consumer;
+
+import org.eclipse.lsp4j.jsonrpc.MessageIssueException;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.CollectionTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.EitherTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.EnumTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.MessageTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.ThrowableTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.TupleTypeAdapters;
+import org.eclipse.lsp4j.jsonrpc.messages.CancelParams;
+import org.eclipse.lsp4j.jsonrpc.messages.Message;
+import org.eclipse.lsp4j.jsonrpc.messages.MessageIssue;
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseErrorCode;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonIOException;
+import com.google.gson.JsonParseException;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.MalformedJsonException;
+
+/**
+ * A wrapper around Gson that includes configuration required for JSON-RPC messages.
+ */
+public class MessageJsonHandler {
+	
+	public static final JsonRpcMethod CANCEL_METHOD = JsonRpcMethod.notification("$/cancelRequest", CancelParams.class);
+
+	private final Gson gson;
+	
+	private final Map<String, JsonRpcMethod> supportedMethods;
+	
+	private MethodProvider methodProvider;
+	
+	/**
+	 * @param supportedMethods - a map used to resolve RPC methods in {@link #getJsonRpcMethod(String)}
+	 */
+	public MessageJsonHandler(Map<String, JsonRpcMethod> supportedMethods) {
+		this.supportedMethods = supportedMethods;
+		this.gson = getDefaultGsonBuilder().create();
+	}
+	
+	/**
+	 * @param supportedMethods - a map used to resolve RPC methods in {@link #getJsonRpcMethod(String)}
+	 * @param configureGson - a function that contributes to the GsonBuilder created by {@link #getDefaultGsonBuilder()}
+	 */
+	public MessageJsonHandler(Map<String, JsonRpcMethod> supportedMethods, Consumer<GsonBuilder> configureGson) {
+		this.supportedMethods = supportedMethods;
+		GsonBuilder gsonBuilder = getDefaultGsonBuilder();
+		configureGson.accept(gsonBuilder);
+		this.gson = gsonBuilder.create();
+	}
+	
+	/**
+	 * Create a {@link GsonBuilder} with default settings for parsing JSON-RPC messages.
+	 */
+	public GsonBuilder getDefaultGsonBuilder() {
+		return new GsonBuilder()
+			.registerTypeAdapterFactory(new CollectionTypeAdapter.Factory())
+			.registerTypeAdapterFactory(new ThrowableTypeAdapter.Factory())
+			.registerTypeAdapterFactory(new EitherTypeAdapter.Factory())
+			.registerTypeAdapterFactory(new TupleTypeAdapters.TwoTypeAdapterFactory())
+			.registerTypeAdapterFactory(new EnumTypeAdapter.Factory())
+			.registerTypeAdapterFactory(new MessageTypeAdapter.Factory(this));
+	}
+	
+	public Gson getGson() {
+		return gson;
+	}
+	
+	/**
+	 * Resolve an RPC method by name.
+	 */
+	public JsonRpcMethod getJsonRpcMethod(String name) {
+		JsonRpcMethod result = supportedMethods.get(name);
+		if (result != null)
+			return result;
+		else if (CANCEL_METHOD.getMethodName().equals(name))
+			return CANCEL_METHOD;
+		return null;
+	}
+	
+	public MethodProvider getMethodProvider() {
+		return methodProvider;
+	}
+	
+	public void setMethodProvider(MethodProvider methodProvider) {
+		this.methodProvider = methodProvider;
+	}
+	
+	public Message parseMessage(CharSequence input) throws JsonParseException {
+		StringReader reader = new StringReader(input.toString());
+		return parseMessage(reader);
+	}
+	
+	public Message parseMessage(Reader input) throws JsonParseException {
+		JsonReader jsonReader = new JsonReader(input);
+		Message message = gson.fromJson(jsonReader, Message.class);
+		
+		if (message != null) {
+			// Check whether the input has been fully consumed
+			try {
+				if (jsonReader.peek() != JsonToken.END_DOCUMENT) {
+					MessageIssue issue = new MessageIssue("JSON document was not fully consumed.", ResponseErrorCode.ParseError.getValue());
+					throw new MessageIssueException(message, issue);
+				}
+			} catch (MalformedJsonException e) {
+				MessageIssue issue = new MessageIssue("Message could not be parsed.", ResponseErrorCode.ParseError.getValue(), e);
+				throw new MessageIssueException(message, issue);
+			} catch (IOException e) {
+				throw new JsonIOException(e);
+			}
+		}
+		return message;
+	}
+	
+	public String serialize(Message message) {
+		StringWriter writer = new StringWriter();
+		serialize(message, writer);
+		return writer.toString();
+	}
+	
+	public void serialize(Message message, Writer output) throws JsonIOException {
+		gson.toJson(message, Message.class, output);
+	}
+	
+	
+	private static MessageJsonHandler toStringInstance;
+	
+	/**
+	 * Perform JSON serialization of the given object using the default configuration of JSON-RPC messages
+	 * enhanced with the pretty printing option.
+	 */
+	public static String toString(Object object) {
+		if (toStringInstance == null) {
+			toStringInstance = new MessageJsonHandler(Collections.emptyMap(), gsonBuilder -> {
+				gsonBuilder.setPrettyPrinting();
+			});
+		}
+		return toStringInstance.gson.toJson(object);
+	}
+	
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/json/MethodProvider.java b/java/org/eclipse/lsp4j/jsonrpc/json/MethodProvider.java
new file mode 100644
index 0000000..3ece1f9
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/json/MethodProvider.java
@@ -0,0 +1,23 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.json;
+
+public interface MethodProvider {
+	
+	/**
+	 * Returns the method name for a given request id, or null if such request id is unknown.
+	 * 
+	 * @return method name or {@code null}
+	 */
+	String resolveMethod(String requestId);
+	
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/json/ResponseJsonAdapter.java b/java/org/eclipse/lsp4j/jsonrpc/json/ResponseJsonAdapter.java
new file mode 100644
index 0000000..3fe62d0
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/json/ResponseJsonAdapter.java
@@ -0,0 +1,30 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.json;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import com.google.gson.TypeAdapterFactory;
+
+/**
+ * An annotation that indicates the Gson {@link TypeAdapterFactory} to use with a request response.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface ResponseJsonAdapter {
+
+  Class<? extends TypeAdapterFactory> value();
+
+}
\ No newline at end of file
diff --git a/java/org/eclipse/lsp4j/jsonrpc/json/StreamMessageConsumer.java b/java/org/eclipse/lsp4j/jsonrpc/json/StreamMessageConsumer.java
new file mode 100644
index 0000000..313c472
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/json/StreamMessageConsumer.java
@@ -0,0 +1,98 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.json;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+
+import org.eclipse.lsp4j.jsonrpc.JsonRpcException;
+import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
+import org.eclipse.lsp4j.jsonrpc.messages.Message;
+
+/**
+ * A message consumer that serializes messages to JSON and sends them to an output stream.
+ */
+public class StreamMessageConsumer implements MessageConsumer, MessageConstants {
+
+	private final String encoding;
+	private final MessageJsonHandler jsonHandler;
+
+	private final Object outputLock = new Object();
+
+	private OutputStream output;
+
+	public StreamMessageConsumer(MessageJsonHandler jsonHandler) {
+		this(null, StandardCharsets.UTF_8.name(), jsonHandler);
+	}
+
+	public StreamMessageConsumer(OutputStream output, MessageJsonHandler jsonHandler) {
+		this(output, StandardCharsets.UTF_8.name(), jsonHandler);
+	}
+
+	public StreamMessageConsumer(OutputStream output, String encoding, MessageJsonHandler jsonHandler) {
+		this.output = output;
+		this.encoding = encoding;
+		this.jsonHandler = jsonHandler;
+	}
+
+	public OutputStream getOutput() {
+		return output;
+	}
+
+	public void setOutput(OutputStream output) {
+		this.output = output;
+	}
+
+	@Override
+	public void consume(Message message) {
+		try {
+			String content = jsonHandler.serialize(message);
+			byte[] contentBytes = content.getBytes(encoding);
+			int contentLength = contentBytes.length;
+
+			String header = getHeader(contentLength);
+			byte[] headerBytes = header.getBytes(StandardCharsets.US_ASCII);
+
+			synchronized (outputLock) {
+				output.write(headerBytes);
+				output.write(contentBytes);
+				output.flush();
+			}
+		} catch (IOException exception) {
+			throw new JsonRpcException(exception);
+		}
+	}
+
+	/**
+	 * Construct a header to be prepended to the actual content. This implementation writes
+	 * {@code Content-Length} and {@code Content-Type} attributes according to the LSP specification.
+	 */
+	protected String getHeader(int contentLength) {
+		StringBuilder headerBuilder = new StringBuilder();
+		appendHeader(headerBuilder, CONTENT_LENGTH_HEADER, contentLength).append(CRLF);
+		if (!StandardCharsets.UTF_8.name().equals(encoding)) {
+			appendHeader(headerBuilder, CONTENT_TYPE_HEADER, JSON_MIME_TYPE);
+			headerBuilder.append("; charset=").append(encoding).append(CRLF);
+		}
+		headerBuilder.append(CRLF);
+		return headerBuilder.toString();
+	}
+
+	/**
+	 * Append a header attribute to the given builder.
+	 */
+	protected StringBuilder appendHeader(StringBuilder builder, String name, Object value) {
+		return builder.append(name).append(": ").append(value);
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/json/StreamMessageProducer.java b/java/org/eclipse/lsp4j/jsonrpc/json/StreamMessageProducer.java
new file mode 100644
index 0000000..835a903
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/json/StreamMessageProducer.java
@@ -0,0 +1,216 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.json;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.eclipse.lsp4j.jsonrpc.JsonRpcException;
+import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
+import org.eclipse.lsp4j.jsonrpc.MessageIssueException;
+import org.eclipse.lsp4j.jsonrpc.MessageIssueHandler;
+import org.eclipse.lsp4j.jsonrpc.MessageProducer;
+import org.eclipse.lsp4j.jsonrpc.messages.Message;
+
+/**
+ * A message producer that reads from an input stream and parses messages from JSON.
+ */
+public class StreamMessageProducer implements MessageProducer, Closeable, MessageConstants {
+
+	private static final Logger LOG = Logger.getLogger(StreamMessageProducer.class.getName());
+
+	private final MessageJsonHandler jsonHandler;
+	private final MessageIssueHandler issueHandler;
+
+	private InputStream input;
+
+	private MessageConsumer callback;
+	private boolean keepRunning;
+
+	public StreamMessageProducer(InputStream input, MessageJsonHandler jsonHandler) {
+		this(input, jsonHandler, null);
+	}
+	
+	public StreamMessageProducer(InputStream input, MessageJsonHandler jsonHandler, MessageIssueHandler issueHandler) {
+		this.input = input;
+		this.jsonHandler = jsonHandler;
+		this.issueHandler = issueHandler;
+	}
+
+	public InputStream getInput() {
+		return input;
+	}
+
+	public void setInput(InputStream input) {
+		this.input = input;
+	}
+
+	protected static class Headers {
+		public int contentLength = -1;
+		public String charset = StandardCharsets.UTF_8.name();
+	}
+
+	@Override
+	public void listen(MessageConsumer callback) {
+		if (keepRunning) {
+			throw new IllegalStateException("This StreamMessageProducer is already running.");
+		}
+		this.keepRunning = true;
+		this.callback = callback;
+		try {
+			StringBuilder headerBuilder = null;
+			StringBuilder debugBuilder = null;
+			boolean newLine = false;
+			Headers headers = new Headers();
+			while (keepRunning) {
+				int c = input.read();
+				if (c == -1) {
+					// End of input stream has been reached
+					keepRunning = false;
+				} else {
+					if (debugBuilder == null)
+						debugBuilder = new StringBuilder();
+					debugBuilder.append((char) c);
+					if (c == '\n') {
+						if (newLine) {
+							// Two consecutive newlines have been read, which signals the start of the message content
+							if (headers.contentLength < 0) {
+								fireError(new IllegalStateException("Missing header " + CONTENT_LENGTH_HEADER
+										+ " in input \"" + debugBuilder + "\""));
+							} else {
+								boolean result = handleMessage(input, headers);
+								if (!result)
+									keepRunning = false;
+								newLine = false;
+							}
+							headers = new Headers();
+							debugBuilder = null;
+						} else if (headerBuilder != null) {
+							// A single newline ends a header line
+							parseHeader(headerBuilder.toString(), headers);
+							headerBuilder = null;
+						}
+						newLine = true;
+					} else if (c != '\r') {
+						// Add the input to the current header line
+						if (headerBuilder == null)
+							headerBuilder = new StringBuilder();
+						headerBuilder.append((char) c);
+						newLine = false;
+					}
+				}
+			} // while (keepRunning)
+		} catch (IOException exception) {
+			if (JsonRpcException.indicatesStreamClosed(exception)) {
+				// Only log the error if we had intended to keep running
+				if (keepRunning)
+					fireStreamClosed(exception);
+			} else
+				throw new JsonRpcException(exception);
+		} finally {
+			this.callback = null;
+			this.keepRunning = false;
+		}
+	}
+
+	/**
+	 * Log an error.
+	 */
+	protected void fireError(Throwable error) {
+		String message = error.getMessage() != null ? error.getMessage() : "An error occurred while processing an incoming message.";
+		LOG.log(Level.SEVERE, message, error);
+	}
+	
+	/**
+	 * Report that the stream was closed through an exception.
+	 */
+	protected void fireStreamClosed(Exception cause) {
+		String message = cause.getMessage() != null ? cause.getMessage() : "The input stream was closed.";
+		LOG.log(Level.INFO, message, cause);
+	}
+
+	/**
+	 * Parse a header attribute and set the corresponding data in the {@link Headers} fields.
+	 */
+	protected void parseHeader(String line, Headers headers) {
+		int sepIndex = line.indexOf(':');
+		if (sepIndex >= 0) {
+			String key = line.substring(0, sepIndex).trim();
+			switch (key) {
+			case CONTENT_LENGTH_HEADER:
+				try {
+					headers.contentLength = Integer.parseInt(line.substring(sepIndex + 1).trim());
+				} catch (NumberFormatException e) {
+					fireError(e);
+				}
+				break;
+			case CONTENT_TYPE_HEADER: {
+				int charsetIndex = line.indexOf("charset=");
+				if (charsetIndex >= 0)
+					headers.charset = line.substring(charsetIndex + 8).trim();
+				break;
+			}
+			}
+		}
+	}
+
+	/**
+	 * Read the JSON content part of a message, parse it, and notify the callback.
+	 * 
+	 * @return {@code true} if we should continue reading from the input stream, {@code false} if we should stop
+	 */
+	protected boolean handleMessage(InputStream input, Headers headers) throws IOException {
+		if (callback == null)
+			callback = message -> LOG.log(Level.INFO, "Received message: " + message);
+		
+		try {
+			int contentLength = headers.contentLength;
+			byte[] buffer = new byte[contentLength];
+			int bytesRead = 0;
+
+			while (bytesRead < contentLength) {
+				int readResult = input.read(buffer, bytesRead, contentLength - bytesRead);
+				if (readResult == -1)
+					return false;
+				bytesRead += readResult;
+			}
+
+			String content = new String(buffer, headers.charset);
+			try {
+				Message message = jsonHandler.parseMessage(content);
+				callback.consume(message);
+			} catch (MessageIssueException exception) {
+				// An issue was found while parsing or validating the message
+				if (issueHandler != null)
+					issueHandler.handle(exception.getRpcMessage(), exception.getIssues());
+				else
+					fireError(exception);
+			}
+		} catch (Exception exception) {
+			// UnsupportedEncodingException can be thrown by String constructor
+			// JsonParseException can be thrown by jsonHandler
+			// We also catch arbitrary exceptions that are thrown by message consumers in order to keep this thread alive
+			fireError(exception);
+		}
+		return true;
+	}
+
+	@Override
+	public void close() {
+		keepRunning = false;
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/json/adapters/CollectionTypeAdapter.java b/java/org/eclipse/lsp4j/jsonrpc/json/adapters/CollectionTypeAdapter.java
new file mode 100644
index 0000000..96d34f8
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/json/adapters/CollectionTypeAdapter.java
@@ -0,0 +1,146 @@
+/******************************************************************************
+ * Copyright (c) 2016-2017 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.json.adapters;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.Queue;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.function.Supplier;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonParseException;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.JsonWriter;
+
+/**
+ * A specialized type adapter for collections that can handle single values.
+ */
+public class CollectionTypeAdapter<E> extends TypeAdapter<Collection<E>> {
+	
+	public static class Factory implements TypeAdapterFactory {
+
+		@Override
+		@SuppressWarnings({ "unchecked" })
+		public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
+			if (!Collection.class.isAssignableFrom(typeToken.getRawType()))
+				return null;
+
+			Type[] elementTypes = TypeUtils.getElementTypes(typeToken, Collection.class);
+			if (elementTypes.length != 1)
+				return null;
+			Type elementType = elementTypes[0];
+			TypeAdapter<?> elementTypeAdapter;
+			if (elementType == Object.class)
+				elementTypeAdapter = new JsonElementTypeAdapter(gson);
+			else
+				elementTypeAdapter = gson.getAdapter(TypeToken.get(elementType));
+			Supplier<Collection<Object>> constructor = getConstructor((Class<Collection<Object>>) typeToken.getRawType());
+			return (TypeAdapter<T>) create(gson, elementType, elementTypeAdapter, constructor);
+		}
+
+		@SuppressWarnings({ "unchecked", "rawtypes" })
+		protected TypeAdapter<?> create(Gson gson, Type elementType, TypeAdapter<?> elementTypeAdapter, Supplier<Collection<Object>> constructor) {
+			return new CollectionTypeAdapter(gson, elementType, elementTypeAdapter, constructor);
+		}
+
+		protected <E> Supplier<Collection<E>> getConstructor(Class<? extends Collection<E>> rawType) {
+			try {
+				Constructor<? extends Collection<E>> constructor = rawType.getDeclaredConstructor();
+				return () -> {
+					try {
+						return constructor.newInstance();
+					} catch (Exception e) {
+						throw new JsonParseException(e);
+					}
+				};
+			} catch (Exception e) {
+				if (SortedSet.class.isAssignableFrom(rawType))
+					return () -> new TreeSet<E>();
+				else if (Set.class.isAssignableFrom(rawType))
+					return () -> new LinkedHashSet<E>();
+				else if (Queue.class.isAssignableFrom(rawType))
+					return () -> new LinkedList<E>();
+				else
+					return () -> new ArrayList<E>();
+			}
+		}
+
+	}
+
+	private final Gson gson;
+	private final Type elementType;
+	private final TypeAdapter<E> elementTypeAdapter;
+	private final Supplier<Collection<E>> constructor;
+
+	public CollectionTypeAdapter(Gson gson, Type elementType, TypeAdapter<E> elementTypeAdapter, Supplier<Collection<E>> constructor) {
+		this.gson = gson;
+		this.elementType = elementType;
+		this.elementTypeAdapter = elementTypeAdapter;
+		this.constructor = constructor;
+	}
+
+	@Override
+	public Collection<E> read(JsonReader in) throws IOException {
+		JsonToken peek = in.peek();
+		if (peek == JsonToken.NULL) {
+			in.nextNull();
+			return null;
+		} else if (peek == JsonToken.BEGIN_ARRAY) {
+			Collection<E> collection = constructor.get();
+			in.beginArray();
+			while (in.hasNext()) {
+				E instance = elementTypeAdapter.read(in);
+				collection.add(instance);
+			}
+			in.endArray();
+			return collection;
+		} else {
+			Collection<E> collection = constructor.get();
+			E instance = elementTypeAdapter.read(in);
+			collection.add(instance);
+			return collection;
+		}
+	}
+
+	@Override
+	public void write(JsonWriter out, Collection<E> collection) throws IOException {
+		if (collection == null) {
+			out.nullValue();
+			return;
+		}
+		out.beginArray();
+		for (E element : collection) {
+			if (element != null && elementType != element.getClass()
+					&& (elementType instanceof TypeVariable<?> || elementType instanceof Class<?>)) {
+				@SuppressWarnings("unchecked")
+				TypeAdapter<E> runtimeTypeAdapter = (TypeAdapter<E>) gson.getAdapter(TypeToken.get(element.getClass()));
+				runtimeTypeAdapter.write(out, element);
+			} else {
+				elementTypeAdapter.write(out, element);
+			}
+		}
+		out.endArray();
+	}
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/json/adapters/CollectionTypeAdapterFactory.java b/java/org/eclipse/lsp4j/jsonrpc/json/adapters/CollectionTypeAdapterFactory.java
new file mode 100644
index 0000000..7a153e2
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/json/adapters/CollectionTypeAdapterFactory.java
@@ -0,0 +1,40 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.json.adapters;
+
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.function.Supplier;
+
+import com.google.gson.Gson;
+import com.google.gson.TypeAdapter;
+
+/**
+ * @deprecated Use {@link CollectionTypeAdapter.Factory} instead.
+ */
+@Deprecated
+public class CollectionTypeAdapterFactory extends CollectionTypeAdapter.Factory {
+	
+	/**
+	 * @deprecated Use {@link CollectionTypeAdapter} instead.
+	 */
+	@Deprecated
+	protected static class Adapter<E> extends CollectionTypeAdapter<E> {
+
+		public Adapter(Gson gson, Type elementType, TypeAdapter<E> elementTypeAdapter,
+				Supplier<Collection<E>> constructor) {
+			super(gson, elementType, elementTypeAdapter, constructor);
+		}
+		
+	}
+	
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/json/adapters/EitherTypeAdapter.java b/java/org/eclipse/lsp4j/jsonrpc/json/adapters/EitherTypeAdapter.java
new file mode 100644
index 0000000..707c506
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/json/adapters/EitherTypeAdapter.java
@@ -0,0 +1,286 @@
+/******************************************************************************
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.json.adapters;
+
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.function.Predicate;
+
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.messages.Either3;
+import org.eclipse.lsp4j.jsonrpc.messages.Tuple;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import com.google.gson.JsonParser;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.JsonWriter;
+
+/**
+ * Type adapter for {@link Either} and {@link Either3}.
+ */
+public class EitherTypeAdapter<L, R> extends TypeAdapter<Either<L, R>> {
+
+	public static class Factory implements TypeAdapterFactory {
+
+		@SuppressWarnings({ "rawtypes", "unchecked" })
+		@Override
+		public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
+			if (!TypeUtils.isEither(typeToken.getType())) {
+				return null;
+			}
+			return new EitherTypeAdapter(gson, typeToken);
+		}
+
+	}
+	
+	/**
+	 * A predicate that is usedful for checking alternatives in case both the left and the right type
+	 * are JSON object types.
+	 */
+	public static class PropertyChecker implements Predicate<JsonElement> {
+		
+		private final String propertyName;
+		private final String expectedValue;
+		private final Class<? extends JsonElement> expectedType;
+		
+		public PropertyChecker(String propertyName) {
+			this.propertyName = propertyName;
+			this.expectedValue = null;
+			this.expectedType = null;
+		}
+		
+		public PropertyChecker(String propertyName, String expectedValue) {
+			this.propertyName = propertyName;
+			this.expectedValue = expectedValue;
+			this.expectedType = null;
+		}
+		
+		public PropertyChecker(String propertyName, Class<? extends JsonElement> expectedType) {
+			this.propertyName = propertyName;
+			this.expectedType = expectedType;
+			this.expectedValue = null;
+		}
+
+		@Override
+		public boolean test(JsonElement element) {
+			if (element.isJsonObject()) {
+				JsonObject object = element.getAsJsonObject();
+				JsonElement value = object.get(propertyName);
+				if (expectedValue != null)
+					return value != null && value.isJsonPrimitive() && expectedValue.equals(value.getAsString());
+				else if (expectedType != null)
+					return expectedType.isInstance(value);
+				else
+					return value != null;
+			}
+			return false;
+		}
+		
+	}
+	
+	/**
+	 * A predicate for the case that a type alternative is a list.
+	 */
+	public static class ListChecker implements Predicate<JsonElement> {
+		
+		private final Predicate<JsonElement> elementChecker;
+		private final boolean resultIfEmpty;
+		
+		public ListChecker(Predicate<JsonElement> elementChecker) {
+			this(elementChecker, false);
+		}
+		
+		public ListChecker(Predicate<JsonElement> elementChecker, boolean resultIfEmpty) {
+			this.elementChecker = elementChecker;
+			this.resultIfEmpty = resultIfEmpty;
+		}
+
+		@Override
+		public boolean test(JsonElement t) {
+			if (elementChecker.test(t))
+				return true;
+			if (t.isJsonArray()) {
+				JsonArray array = t.getAsJsonArray();
+				if (array.size() == 0)
+					return resultIfEmpty;
+				for (JsonElement e : array) {
+					if (elementChecker.test(e))
+						return true;
+				}
+			}
+			return false;
+		}
+		
+	}
+
+	protected final TypeToken<Either<L, R>> typeToken;
+	protected final EitherTypeArgument<L> left;
+	protected final EitherTypeArgument<R> right;
+	protected final Predicate<JsonElement> leftChecker;
+	protected final Predicate<JsonElement> rightChecker;
+
+	public EitherTypeAdapter(Gson gson, TypeToken<Either<L, R>> typeToken) {
+		this(gson, typeToken, null, null);
+	}
+	
+	public EitherTypeAdapter(Gson gson, TypeToken<Either<L, R>> typeToken, Predicate<JsonElement> leftChecker, Predicate<JsonElement> rightChecker) {
+		this.typeToken = typeToken;
+		Type[] elementTypes = TypeUtils.getElementTypes(typeToken, Either.class);
+		this.left = new EitherTypeArgument<L>(gson, elementTypes[0]);
+		this.right = new EitherTypeArgument<R>(gson, elementTypes[1]);
+		this.leftChecker = leftChecker;
+		this.rightChecker = rightChecker;
+	}
+
+	@Override
+	public void write(JsonWriter out, Either<L, R> value) throws IOException {
+		if (value == null) {
+			out.nullValue();
+		} else if (value.isLeft()) {
+			left.write(out, value.getLeft());
+		} else {
+			right.write(out, value.getRight());
+		}
+	}
+
+	@Override
+	public Either<L, R> read(JsonReader in) throws IOException {
+		JsonToken next = in.peek();
+		if (next == JsonToken.NULL) {
+			in.nextNull();
+			return null;
+		}
+		return create(next, in);
+	}
+
+	protected Either<L, R> create(JsonToken nextToken, JsonReader in) throws IOException {
+		boolean matchesLeft = left.isAssignable(nextToken);
+		boolean matchesRight = right.isAssignable(nextToken);
+		if (matchesLeft && matchesRight) {
+			if (leftChecker != null || rightChecker != null) {
+				JsonElement element = JsonParser.parseReader(in);
+				if (leftChecker != null && leftChecker.test(element))
+					// Parse the left alternative from the JSON element tree
+					return createLeft(left.read(element));
+				if (rightChecker != null && rightChecker.test(element))
+					// Parse the right alternative from the JSON element tree
+					return createRight(right.read(element));
+			}
+			throw new JsonParseException("Ambiguous Either type: token " + nextToken + " matches both alternatives.");
+		} else if (matchesLeft) {
+			// Parse the left alternative from the JSON stream
+			return createLeft(left.read(in));
+		} else if (matchesRight) {
+			// Parse the right alternative from the JSON stream
+			return createRight(right.read(in));
+		} else if (leftChecker != null || rightChecker != null) {
+			// If result is not the list but directly the only item in the list
+			JsonElement element = JsonParser.parseReader(in);
+			if (leftChecker != null && leftChecker.test(element))
+				// Parse the left alternative from the JSON element tree
+				return createLeft(left.read(element));
+			if (rightChecker != null && rightChecker.test(element))
+				// Parse the right alternative from the JSON element tree
+				return createRight(right.read(element));
+		}
+		throw new JsonParseException("Unexpected token " + nextToken + ": expected " + left + " | " + right + " tokens.");
+	}
+	
+	@SuppressWarnings("unchecked")
+	protected Either<L, R> createLeft(L obj) throws IOException {
+		if (Either3.class.isAssignableFrom(typeToken.getRawType()))
+			return (Either<L, R>) Either3.forLeft3(obj);
+		return Either.forLeft(obj);
+	}
+	
+	@SuppressWarnings("unchecked")
+	protected Either<L, R> createRight(R obj) throws IOException {
+		if (Either3.class.isAssignableFrom(typeToken.getRawType()))
+			return (Either<L, R>) Either3.forRight3((Either<?, ?>) obj);
+		return Either.forRight(obj);
+	}
+
+	protected static class EitherTypeArgument<T> {
+
+		protected final TypeToken<T> typeToken;
+		protected final TypeAdapter<T> adapter;
+		protected final Collection<JsonToken> expectedTokens;
+
+		@SuppressWarnings("unchecked")
+		public EitherTypeArgument(Gson gson, Type type) {
+			this.typeToken = (TypeToken<T>) TypeToken.get(type);
+			this.adapter = (type == Object.class) ? (TypeAdapter<T>) new JsonElementTypeAdapter(gson) : gson.getAdapter(this.typeToken);
+			this.expectedTokens = new HashSet<>();
+			for (Type expectedType : TypeUtils.getExpectedTypes(type)) {
+				Class<?> rawType = TypeToken.get(expectedType).getRawType();
+				JsonToken expectedToken = getExpectedToken(rawType);
+				expectedTokens.add(expectedToken);
+			}
+		}
+
+		protected JsonToken getExpectedToken(Class<?> rawType) {
+			if (rawType.isArray() || Collection.class.isAssignableFrom(rawType) || Tuple.class.isAssignableFrom(rawType)) {
+				return JsonToken.BEGIN_ARRAY;
+			}
+			if (Boolean.class.isAssignableFrom(rawType)) {
+				return JsonToken.BOOLEAN;
+			}
+			if (Number.class.isAssignableFrom(rawType) || Enum.class.isAssignableFrom(rawType)) {
+				return JsonToken.NUMBER;
+			}
+			if (Character.class.isAssignableFrom(rawType) || String.class.isAssignableFrom(rawType)) {
+				return JsonToken.STRING;
+			}
+			return JsonToken.BEGIN_OBJECT;
+		}
+
+		public boolean isAssignable(JsonToken jsonToken) {
+			return this.expectedTokens.contains(jsonToken);
+		}
+
+		public void write(JsonWriter out, T value) throws IOException {
+			this.adapter.write(out, value);
+		}
+
+		public T read(JsonReader in) throws IOException {
+			return this.adapter.read(in);
+		}
+		
+		public T read(JsonElement element) throws IOException {
+			return this.adapter.fromJsonTree(element);
+		}
+
+		@Override
+		public String toString() {
+			StringBuilder builder = new StringBuilder();
+			for (JsonToken expectedToken : expectedTokens) {
+				if (builder.length() != 0) {
+					builder.append(" | ");
+				}
+				builder.append(expectedToken);
+			}
+			return builder.toString();
+		}
+
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/json/adapters/EitherTypeAdapterFactory.java b/java/org/eclipse/lsp4j/jsonrpc/json/adapters/EitherTypeAdapterFactory.java
new file mode 100644
index 0000000..5abbe83
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/json/adapters/EitherTypeAdapterFactory.java
@@ -0,0 +1,37 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.json.adapters;
+
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+
+/**
+ * @deprecated Use {@link EitherTypeAdapter.Factory} instead.
+ */
+@Deprecated
+public class EitherTypeAdapterFactory extends EitherTypeAdapter.Factory {
+	
+	/**
+	 * @deprecated Use {@link EitherTypeAdapter} instead.
+	 */
+	@Deprecated
+	protected static class Adapter<L, R> extends EitherTypeAdapter<L, R> {
+
+		public Adapter(Gson gson, TypeToken<Either<L, R>> typeToken) {
+			super(gson, typeToken);
+		}
+		
+	}
+	
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/json/adapters/EnumTypeAdapter.java b/java/org/eclipse/lsp4j/jsonrpc/json/adapters/EnumTypeAdapter.java
new file mode 100644
index 0000000..c24ded2
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/json/adapters/EnumTypeAdapter.java
@@ -0,0 +1,105 @@
+/******************************************************************************
+ * Copyright (c) 2016-2017 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.json.adapters;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.google.gson.Gson;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.JsonWriter;
+
+/**
+ * A custom type adapter for enums that uses integer values.
+ */
+public class EnumTypeAdapter<T extends Enum<T>> extends TypeAdapter<T> {
+	
+	public static class Factory implements TypeAdapterFactory {
+
+		@Override
+		@SuppressWarnings({ "unchecked", "rawtypes" })
+		public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
+			Class<?> rawType = typeToken.getRawType();
+			if (!Enum.class.isAssignableFrom(rawType) || rawType == Enum.class)
+				return null;
+			if (!rawType.isEnum())
+				rawType = rawType.getSuperclass();
+			try {
+				return new EnumTypeAdapter(rawType);
+			} catch (IllegalAccessException e) {
+				throw new RuntimeException(e);
+			}
+		}
+		
+	}
+	
+	private static String VALUE_FIELD_NAME = "value";
+	
+	private final Map<String, T> nameToConstant = new HashMap<>();
+	private final Map<Integer, T> valueToConstant = new HashMap<>();
+	private final Map<T, Integer> constantToValue = new HashMap<>();
+	
+	EnumTypeAdapter(Class<T> classOfT) throws IllegalAccessException {
+		try {
+			Field valueField = classOfT.getDeclaredField(VALUE_FIELD_NAME);
+			if (valueField.getType() != int.class && valueField.getType() != Integer.class)
+				throw new IllegalArgumentException("The field 'value' must contain an integer value.");
+			valueField.setAccessible(true);
+			for (T constant : classOfT.getEnumConstants()) {
+				nameToConstant.put(constant.name(), constant);
+				Integer constValue = (Integer) valueField.get(constant);
+				valueToConstant.put(constValue, constant);
+				constantToValue.put(constant, constValue);
+			}
+		} catch (NoSuchFieldException e) {
+			for (T constant : classOfT.getEnumConstants()) {
+				nameToConstant.put(constant.name(), constant);
+				int constValue = constant.ordinal();
+				valueToConstant.put(constValue, constant);
+				constantToValue.put(constant, constValue);
+			}
+		}
+	}
+	
+	@Override
+	public T read(JsonReader in) throws IOException {
+		JsonToken peek = in.peek();
+		if (peek == JsonToken.NULL) {
+			in.nextNull();
+			return null;
+		} else if (peek == JsonToken.NUMBER) {
+			return valueToConstant.get(in.nextInt());
+		} else {
+			String string = in.nextString();
+			try {
+				return valueToConstant.get(Integer.parseInt(string));
+			} catch (NumberFormatException e) {
+				return nameToConstant.get(string);
+			}
+		}
+	}
+
+	@Override
+	public void write(JsonWriter out, T value) throws IOException {
+		if (value != null)
+			out.value(constantToValue.get(value));
+		else
+			out.value((String) null);
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/json/adapters/EnumTypeAdapterFactory.java b/java/org/eclipse/lsp4j/jsonrpc/json/adapters/EnumTypeAdapterFactory.java
new file mode 100644
index 0000000..ee23dde
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/json/adapters/EnumTypeAdapterFactory.java
@@ -0,0 +1,20 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.json.adapters;
+
+/**
+ * @deprecated Use {@link EnumTypeAdapter.Factory} instead.
+ */
+@Deprecated
+public class EnumTypeAdapterFactory extends EnumTypeAdapter.Factory {
+	
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/json/adapters/JsonElementTypeAdapter.java b/java/org/eclipse/lsp4j/jsonrpc/json/adapters/JsonElementTypeAdapter.java
new file mode 100644
index 0000000..0e19daa
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/json/adapters/JsonElementTypeAdapter.java
@@ -0,0 +1,68 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.json.adapters;
+
+import java.io.IOException;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+
+/**
+ * A type adapter that reads every input into a tree of {@link JsonElement}s.
+ */
+public class JsonElementTypeAdapter extends TypeAdapter<Object> {
+	
+	/**
+	 * This factory should not be registered with a GsonBuilder because it always matches.
+	 * Use it as argument to a {@link com.google.gson.annotations.JsonAdapter} annotation like this:
+	 * {@code @JsonAdapter(JsonElementTypeAdapter.Factory.class)}
+	 */
+	public static class Factory implements TypeAdapterFactory {
+
+		@SuppressWarnings("unchecked")
+		@Override
+		public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
+			return (TypeAdapter<T>) new JsonElementTypeAdapter(gson);
+		}
+		
+	}
+	
+	private final Gson gson;
+	private final TypeAdapter<JsonElement> adapter;
+
+	public JsonElementTypeAdapter(Gson gson) {
+		this.gson = gson;
+		this.adapter = gson.getAdapter(JsonElement.class);
+	}
+	
+	@Override
+	public JsonElement read(JsonReader in) throws IOException {
+		return adapter.read(in);
+	}
+
+	@Override
+	public void write(JsonWriter out, Object value) throws IOException {
+		if (value == null) {
+			out.nullValue();
+		} else if (value instanceof JsonElement) {
+			adapter.write(out, (JsonElement) value);
+		} else {
+			gson.toJson(value, value.getClass(), out);;
+		}
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/json/adapters/MessageTypeAdapter.java b/java/org/eclipse/lsp4j/jsonrpc/json/adapters/MessageTypeAdapter.java
new file mode 100644
index 0000000..bffdecb
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/json/adapters/MessageTypeAdapter.java
@@ -0,0 +1,459 @@
+/******************************************************************************
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.json.adapters;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.lsp4j.jsonrpc.MessageIssueException;
+import org.eclipse.lsp4j.jsonrpc.json.JsonRpcMethod;
+import org.eclipse.lsp4j.jsonrpc.json.MessageConstants;
+import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
+import org.eclipse.lsp4j.jsonrpc.json.MethodProvider;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.messages.Message;
+import org.eclipse.lsp4j.jsonrpc.messages.MessageIssue;
+import org.eclipse.lsp4j.jsonrpc.messages.NotificationMessage;
+import org.eclipse.lsp4j.jsonrpc.messages.RequestMessage;
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseError;
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseErrorCode;
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonIOException;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonParseException;
+import com.google.gson.JsonParser;
+import com.google.gson.JsonSyntaxException;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.JsonWriter;
+import com.google.gson.stream.MalformedJsonException;
+
+/**
+ * The type adapter for messages dispatches between the different message types: {@link RequestMessage},
+ * {@link ResponseMessage}, and {@link NotificationMessage}.
+ */
+public class MessageTypeAdapter extends TypeAdapter<Message> {
+	
+	public static class Factory implements TypeAdapterFactory {
+		
+		private final MessageJsonHandler handler;
+		
+		public Factory(MessageJsonHandler handler) {
+			this.handler = handler;
+		}
+
+		@Override
+		@SuppressWarnings("unchecked")
+		public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
+			if (!Message.class.isAssignableFrom(typeToken.getRawType()))
+				return null;
+			return (TypeAdapter<T>) new MessageTypeAdapter(handler, gson);
+		}
+		
+	}
+	
+	private static Type[] EMPTY_TYPE_ARRAY = {};
+
+	private final MessageJsonHandler handler;
+	private final Gson gson;
+	
+	public MessageTypeAdapter(MessageJsonHandler handler, Gson gson) {
+		this.handler = handler;
+		this.gson = gson;
+	}
+
+	@Override
+	public Message read(JsonReader in) throws IOException, JsonIOException, JsonSyntaxException {
+		if (in.peek() == JsonToken.NULL) {
+			in.nextNull();
+			return null;
+		}
+		
+		in.beginObject();
+		String jsonrpc = null, method = null;
+		Either<String, Number> id = null;
+		Object rawParams = null;
+		Object rawResult = null;
+		ResponseError responseError = null;
+		try {
+			
+			while (in.hasNext()) {
+				String name = in.nextName();
+				switch (name) {
+				case "jsonrpc": {
+					jsonrpc = in.nextString();
+					break;
+				}
+				case "id": {
+					if (in.peek() == JsonToken.NUMBER)
+						id = Either.forRight(in.nextInt());
+					else
+						id = Either.forLeft(in.nextString());
+					break;
+				}
+				case "method": {
+					method = in.nextString();
+					break;
+				}
+				case "params": {
+					rawParams = parseParams(in, method);
+					break;
+				}
+				case "result": {
+					rawResult = parseResult(in, id != null ? id.get().toString() : null);
+					break;
+				}
+				case "error": {
+					responseError = gson.fromJson(in, ResponseError.class);
+					break;
+				}
+				default:
+					in.skipValue();
+				}
+			}
+			Object params = parseParams(rawParams, method);
+			Object result = parseResult(rawResult, id != null ? id.get().toString() : null);
+			
+			in.endObject();
+			return createMessage(jsonrpc, id, method, params, result, responseError);
+			
+		} catch (JsonSyntaxException | MalformedJsonException | EOFException exception) {
+			if (id != null || method != null) {
+				// Create a message and bundle it to an exception with an issue that wraps the original exception
+				Message message = createMessage(jsonrpc, id, method, rawParams, rawResult, responseError);
+				MessageIssue issue = new MessageIssue("Message could not be parsed.", ResponseErrorCode.ParseError.getValue(), exception);
+				throw new MessageIssueException(message, issue);
+			} else {
+				throw exception;
+			}
+		}
+	}
+
+	/**
+	 * Convert the json input into the result object corresponding to the call made
+	 * by id.
+	 *
+	 * If the id is not known until after parsing, call
+	 * {@link #parseResult(Object, String)} on the return value of this call for a
+	 * second chance conversion.
+	 *
+	 * @param in
+	 *            json input to read from
+	 * @param id
+	 *            id of request message this is in response to
+	 * @return correctly typed object if the correct expected type can be
+	 *         determined, or a JsonElement representing the result
+	 */
+	protected Object parseResult(JsonReader in, String id) throws JsonIOException, JsonSyntaxException {
+		Type type = null;
+		MethodProvider methodProvider = handler.getMethodProvider();
+		if (methodProvider != null && id != null) {
+			String resolvedMethod = methodProvider.resolveMethod(id);
+			if (resolvedMethod != null) {
+				JsonRpcMethod jsonRpcMethod = handler.getJsonRpcMethod(resolvedMethod);
+				if (jsonRpcMethod != null) {
+					type = jsonRpcMethod.getReturnType();
+					if (jsonRpcMethod.getReturnTypeAdapterFactory() != null) {
+						TypeAdapter<?> typeAdapter = jsonRpcMethod.getReturnTypeAdapterFactory().create(gson, TypeToken.get(type));
+						try {
+							if (typeAdapter != null)
+								return typeAdapter.read(in);
+						} catch (IOException exception) {
+							throw new JsonIOException(exception);
+						}
+					}
+				}
+			}
+		}
+		return fromJson(in, type);
+	}
+
+	/**
+	 * Convert the JsonElement into the result object corresponding to the call made
+	 * by id. If the result is already converted, does nothing.
+	 *
+	 * @param result
+	 *            json element to read from
+	 * @param id
+	 *            id of request message this is in response to
+	 * @return correctly typed object if the correct expected type can be
+	 *         determined, or result unmodified if no conversion can be done.
+	 */
+	protected Object parseResult(Object result, String id) throws JsonSyntaxException {
+		if (result instanceof JsonElement) {
+			// Type of result could not be resolved - try again with the parsed JSON tree
+			Type type = null;
+			MethodProvider methodProvider = handler.getMethodProvider();
+			if (methodProvider != null) {
+				String resolvedMethod = methodProvider.resolveMethod(id);
+				if (resolvedMethod != null) {
+					JsonRpcMethod jsonRpcMethod = handler.getJsonRpcMethod(resolvedMethod);
+					if (jsonRpcMethod != null) {
+						type = jsonRpcMethod.getReturnType();
+						if (jsonRpcMethod.getReturnTypeAdapterFactory() != null) {
+							TypeAdapter<?> typeAdapter = jsonRpcMethod.getReturnTypeAdapterFactory().create(gson, TypeToken.get(type));
+							if (typeAdapter != null)
+								return typeAdapter.fromJsonTree((JsonElement) result);
+						}
+					}
+				}
+			}
+			return fromJson((JsonElement) result, type);
+		}
+		return result;
+	}
+
+	/**
+	 * Convert the json input into the parameters object corresponding to the call
+	 * made by method.
+	 *
+	 * If the method is not known until after parsing, call
+	 * {@link #parseParams(Object, String)} on the return value of this call for a
+	 * second chance conversion.
+	 *
+	 * @param in
+	 *            json input to read from
+	 * @param method
+	 *            method name of request
+	 * @return correctly typed object if the correct expected type can be
+	 *         determined, or a JsonElement representing the parameters
+	 */
+	protected Object parseParams(JsonReader in, String method) throws IOException, JsonIOException {
+		JsonToken next = in.peek();
+		if (next == JsonToken.NULL) {
+			in.nextNull();
+			return null;
+		}
+		Type[] parameterTypes = getParameterTypes(method);
+		if (parameterTypes.length == 1) {
+			return fromJson(in, parameterTypes[0]);
+		}
+		if (parameterTypes.length > 1 && next == JsonToken.BEGIN_ARRAY) {
+			List<Object> parameters = new ArrayList<Object>(parameterTypes.length);
+			int index = 0;
+			in.beginArray();
+			while (in.hasNext()) {
+				Type parameterType = index < parameterTypes.length ? parameterTypes[index] : null;
+				Object parameter = fromJson(in, parameterType);
+				parameters.add(parameter);
+				index++;
+			}
+			in.endArray();
+			while (index < parameterTypes.length) {
+				parameters.add(null);
+				index++;
+			}
+			return parameters;
+		}
+		JsonElement rawParams = JsonParser.parseReader(in);
+		if (method != null && parameterTypes.length == 0 && (
+				rawParams.isJsonArray() && rawParams.getAsJsonArray().size() == 0
+				|| rawParams.isJsonObject() && rawParams.getAsJsonObject().size() == 0)) {
+			return null;
+		}
+		return rawParams;
+	}
+
+	/**
+	 * Convert the JsonElement into the parameters object corresponding to the call made
+	 * by method. If the result is already converted, does nothing.
+	 *
+	 * @param params
+	 *            json element to read from
+	 * @param method
+	 *            method name of request
+	 * @return correctly typed object if the correct expected type can be
+	 *         determined, or params unmodified if no conversion can be done.
+	 */
+	protected Object parseParams(Object params, String method) {
+		if (isNull(params)) {
+			return null;
+		}
+		if (!(params instanceof JsonElement)) {
+			return params;
+		}
+		JsonElement rawParams = (JsonElement) params;
+		Type[] parameterTypes = getParameterTypes(method);
+		if (parameterTypes.length == 1) {
+			return fromJson(rawParams, parameterTypes[0]);
+		}
+		if (parameterTypes.length > 1 && rawParams instanceof JsonArray) {
+			JsonArray array = (JsonArray) rawParams;
+			List<Object> parameters = new ArrayList<Object>(Math.max(array.size(), parameterTypes.length));
+			int index = 0;
+			Iterator<JsonElement> iterator = array.iterator();
+			while (iterator.hasNext()) {
+				Type parameterType = index < parameterTypes.length ? parameterTypes[index] : null;  
+				Object parameter = fromJson(iterator.next(), parameterType);
+				parameters.add(parameter);
+				index++;
+			}
+			while (index < parameterTypes.length) {
+				parameters.add(null);
+				index++;
+			}
+			return parameters;
+		}
+		if (method != null && parameterTypes.length == 0 && (
+				rawParams.isJsonArray() && rawParams.getAsJsonArray().size() == 0
+				|| rawParams.isJsonObject() && rawParams.getAsJsonObject().size() == 0)) {
+			return null;
+		}
+		return rawParams;
+	}
+
+	protected Object fromJson(JsonReader in, Type type) throws JsonIOException {
+		if (isNullOrVoidType(type)) {
+			return JsonParser.parseReader(in);
+		}
+		return gson.fromJson(in, type);
+	}
+	
+	protected Object fromJson(JsonElement element, Type type) {
+		if (isNull(element)) {
+			return null;
+		}
+		if (isNullOrVoidType(type)) {
+			return element;
+		}
+		Object value = gson.fromJson(element, type);
+		if (isNull(value)) {
+			return null;
+		}
+		return value;
+	}
+
+	protected boolean isNull(Object value) {
+		return value == null || value instanceof JsonNull;
+	}
+	
+	protected boolean isNullOrVoidType(Type type) {
+		return type == null || Void.class == type;
+	}
+
+	protected Type[] getParameterTypes(String method) {
+		if (method != null) {
+			JsonRpcMethod jsonRpcMethod = handler.getJsonRpcMethod(method);
+			if (jsonRpcMethod != null)
+				return jsonRpcMethod.getParameterTypes();
+		}
+		return EMPTY_TYPE_ARRAY;
+	}
+	
+	protected Message createMessage(String jsonrpc, Either<String, Number> id, String method, Object params,
+			Object responseResult, ResponseError responseError) throws JsonParseException {
+		if (id != null && method != null) {
+			RequestMessage message = new RequestMessage();
+			message.setJsonrpc(jsonrpc);
+			message.setRawId(id);
+			message.setMethod(method);
+			message.setParams(params);
+			return message;
+		} else if (id != null) {
+			ResponseMessage message = new ResponseMessage();
+			message.setJsonrpc(jsonrpc);
+			message.setRawId(id);
+			if (responseError != null)
+				message.setError(responseError);
+			else
+				message.setResult(responseResult);
+			return message;
+		} else if (method != null) {
+			NotificationMessage message = new NotificationMessage();
+			message.setJsonrpc(jsonrpc);
+			message.setMethod(method);
+			message.setParams(params);
+			return message;
+		} else {
+			throw new JsonParseException("Unable to identify the input message.");
+		}
+	}
+
+	@Override
+	public void write(JsonWriter out, Message message) throws IOException {
+		out.beginObject();
+		out.name("jsonrpc");
+		out.value(message.getJsonrpc() == null ? MessageConstants.JSONRPC_VERSION : message.getJsonrpc());
+		
+		if (message instanceof RequestMessage) {
+			RequestMessage requestMessage = (RequestMessage) message;
+			out.name("id");
+			writeId(out, requestMessage.getRawId());
+			out.name("method");
+			out.value(requestMessage.getMethod());
+			out.name("params");
+			Object params = requestMessage.getParams();
+			if (params == null)
+				writeNullValue(out);
+			else
+				gson.toJson(params, params.getClass(), out);
+		} else if (message instanceof ResponseMessage) {
+			ResponseMessage responseMessage = (ResponseMessage) message;
+			out.name("id");
+			writeId(out, responseMessage.getRawId());
+			if (responseMessage.getError() != null) {
+				out.name("error");
+				gson.toJson(responseMessage.getError(), ResponseError.class, out);
+			} else {
+				out.name("result");
+				Object result = responseMessage.getResult();
+				if (result == null)
+					writeNullValue(out);
+				else
+					gson.toJson(result, result.getClass(), out);
+			}
+		} else if (message instanceof NotificationMessage) {
+			NotificationMessage notificationMessage = (NotificationMessage) message;
+			out.name("method");
+			out.value(notificationMessage.getMethod());
+			out.name("params");
+			Object params = notificationMessage.getParams();
+			if (params == null)
+				writeNullValue(out);
+			else
+				gson.toJson(params, params.getClass(), out);
+		}
+		
+		out.endObject();
+	}
+	
+	protected void writeId(JsonWriter out, Either<String, Number> id) throws IOException {
+		if (id == null)
+			writeNullValue(out);
+		else if (id.isLeft())
+			out.value(id.getLeft());
+		else if (id.isRight())
+			out.value(id.getRight());
+	}
+	
+	/**
+	 * Use this method to write a {@code null} value even if the JSON writer is set to not serialize {@code null}.
+	 */
+	protected void writeNullValue(JsonWriter out) throws IOException {
+		boolean previousSerializeNulls = out.getSerializeNulls();
+		out.setSerializeNulls(true);
+		out.nullValue();
+		out.setSerializeNulls(previousSerializeNulls);
+	}
+	
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/json/adapters/MessageTypeAdapterFactory.java b/java/org/eclipse/lsp4j/jsonrpc/json/adapters/MessageTypeAdapterFactory.java
new file mode 100644
index 0000000..8afa239
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/json/adapters/MessageTypeAdapterFactory.java
@@ -0,0 +1,26 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.json.adapters;
+
+import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
+
+/**
+ * @deprecated Use {@link MessageTypeAdapter.Factory} instead.
+ */
+@Deprecated
+public class MessageTypeAdapterFactory extends MessageTypeAdapter.Factory {
+
+	public MessageTypeAdapterFactory(MessageJsonHandler handler) {
+		super(handler);
+	}
+	
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/json/adapters/ThrowableTypeAdapter.java b/java/org/eclipse/lsp4j/jsonrpc/json/adapters/ThrowableTypeAdapter.java
new file mode 100644
index 0000000..caaaf94
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/json/adapters/ThrowableTypeAdapter.java
@@ -0,0 +1,136 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.json.adapters;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonParseException;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.JsonWriter;
+
+/**
+ * A type adapter for {@link Throwable}. This is used to report issues to the sender of a request.
+ */
+public class ThrowableTypeAdapter extends TypeAdapter<Throwable> {
+	
+	public static class Factory implements TypeAdapterFactory {
+
+		@SuppressWarnings({ "unchecked" })
+		@Override
+		public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
+			if (!Throwable.class.isAssignableFrom(typeToken.getRawType()))
+				return null;
+			
+			return (TypeAdapter<T>) new ThrowableTypeAdapter((TypeToken<Throwable>) typeToken);
+		}
+
+	}
+	
+	private final TypeToken<Throwable> typeToken;
+	
+	public ThrowableTypeAdapter(TypeToken<Throwable> typeToken) {
+		this.typeToken = typeToken;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public Throwable read(JsonReader in) throws IOException {
+		if (in.peek() == JsonToken.NULL) {
+			in.nextNull();
+			return null;
+		}
+		
+		in.beginObject();
+		String message = null;
+		Throwable cause = null;
+		while (in.hasNext()) {
+			String name = in.nextName();
+			switch (name) {
+			case "message": {
+				message = in.nextString();
+				break;
+			}
+			case "cause": {
+				cause = read(in);
+				break;
+			}
+			default:
+				in.skipValue();
+			}
+		}
+		in.endObject();
+		
+		try {
+			Constructor<Throwable> constructor;
+			if (message == null && cause == null) {
+				constructor = (Constructor<Throwable>) typeToken.getRawType().getDeclaredConstructor();
+				return constructor.newInstance();
+			} else if (message == null) {
+				constructor = (Constructor<Throwable>) typeToken.getRawType().getDeclaredConstructor(Throwable.class);
+				return constructor.newInstance(cause);
+			} else if (cause == null) {
+				constructor = (Constructor<Throwable>) typeToken.getRawType().getDeclaredConstructor(String.class);
+				return constructor.newInstance(message);
+			} else {
+				constructor = (Constructor<Throwable>) typeToken.getRawType().getDeclaredConstructor(String.class, Throwable.class);
+				return constructor.newInstance(message, cause);
+			}
+		} catch (NoSuchMethodException e) {
+			if (message == null && cause == null)
+				return new RuntimeException();
+			else if (message == null)
+				return new RuntimeException(cause);
+			else if (cause == null)
+				return new RuntimeException(message);
+			else
+				return new RuntimeException(message, cause);
+		} catch (Exception e) {
+			throw new JsonParseException(e);
+		}
+	}
+
+	@Override
+	public void write(JsonWriter out, Throwable throwable) throws IOException {
+		if (throwable == null) {
+			out.nullValue();
+		} else if (throwable.getMessage() == null && throwable.getCause() != null) {
+			write(out, throwable.getCause());
+		} else {
+			out.beginObject();
+			if (throwable.getMessage() != null) {
+				out.name("message");
+				out.value(throwable.getMessage());
+			}
+			if (shouldWriteCause(throwable)) {
+				out.name("cause");
+				write(out, throwable.getCause());
+			}
+			out.endObject();
+		}
+	}
+	
+	private boolean shouldWriteCause(Throwable throwable) {
+		Throwable cause = throwable.getCause();
+		if (cause == null || cause.getMessage() == null || cause == throwable)
+			return false;
+		if (throwable.getMessage() != null && throwable.getMessage().contains(cause.getMessage()))
+			return false;
+		return true;
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/json/adapters/TupleTypeAdapters.java b/java/org/eclipse/lsp4j/jsonrpc/json/adapters/TupleTypeAdapters.java
new file mode 100644
index 0000000..2214f03
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/json/adapters/TupleTypeAdapters.java
@@ -0,0 +1,74 @@
+package org.eclipse.lsp4j.jsonrpc.json.adapters;
+
+import java.io.IOException;
+import java.lang.reflect.Type;
+
+import org.eclipse.lsp4j.jsonrpc.messages.Tuple.Two;
+
+import com.google.gson.Gson;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.JsonWriter;
+
+public final class TupleTypeAdapters {
+	
+	private TupleTypeAdapters() {}
+
+	public static class TwoTypeAdapter<F extends Object, S extends Object> extends TypeAdapter<Two<F, S>> {
+		
+		protected final TypeAdapter<F> first;
+		protected final TypeAdapter<S> second;
+		
+		@SuppressWarnings("unchecked")
+		public TwoTypeAdapter(Gson gson, TypeToken<Two<F, S>> typeToken) {
+			Type[] elementTypes = TypeUtils.getElementTypes(typeToken, Two.class);
+			this.first = gson.getAdapter((TypeToken<F>) TypeToken.get(elementTypes[0]));
+			this.second = gson.getAdapter((TypeToken<S>) TypeToken.get(elementTypes[1]));
+		}
+
+		@Override
+		public void write(final JsonWriter out, final Two<F, S> value) throws IOException {
+			if (value == null) {
+				out.nullValue();
+			} else {
+				out.beginArray();
+				first.write(out, value.getFirst());
+				second.write(out, value.getSecond());
+				out.endArray();
+			}
+		}
+		
+		@Override
+		public Two<F, S> read(final JsonReader in) throws IOException {
+			JsonToken next = in.peek();
+			if (next == JsonToken.NULL) {
+				in.nextNull();
+				return null;
+			}
+			in.beginArray();
+			F f = first.read(in);
+			S s = second.read(in);
+			Two<F, S> result = new Two<F, S>(f, s);
+			in.endArray();
+			return result;
+		}
+		
+	}
+
+	public static class TwoTypeAdapterFactory implements TypeAdapterFactory {
+
+		@SuppressWarnings({ "rawtypes", "unchecked" })
+		@Override
+		public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
+			if (!TypeUtils.isTwoTuple(typeToken.getType())) {
+				return null;
+			}
+			return new TwoTypeAdapter(gson, typeToken);
+		}
+
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/json/adapters/TypeUtils.java b/java/org/eclipse/lsp4j/jsonrpc/json/adapters/TypeUtils.java
new file mode 100644
index 0000000..11e4530
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/json/adapters/TypeUtils.java
@@ -0,0 +1,242 @@
+/******************************************************************************
+ * Copyright (c) 2017 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.json.adapters;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.messages.Tuple;
+
+import com.google.gson.reflect.TypeToken;
+
+/**
+ * Utilities for handling types in the JSON parser / serializer.
+ */
+public final class TypeUtils {
+	
+	private TypeUtils() {}
+	
+	/**
+	 * Determine the actual type arguments of the given type token with regard to the given target type.
+	 */
+	public static Type[] getElementTypes(TypeToken<?> typeToken, Class<?> targetType) {
+		return getElementTypes(typeToken.getType(), typeToken.getRawType(), targetType);
+	}
+	
+	private static Type[] getElementTypes(Type type, Class<?> rawType, Class<?> targetType) {
+		if (targetType.equals(rawType) && type instanceof ParameterizedType) {
+			Type mappedType;
+			if (type instanceof ParameterizedTypeImpl)
+				mappedType = type;
+			else
+				// Transform wildcards in the actual type arguments
+				mappedType = getMappedType(type, Collections.emptyMap());
+			return ((ParameterizedType) mappedType).getActualTypeArguments();
+		}
+		// Map the parameters of the raw type to the actual type arguments
+		Map<String, Type> varMapping = createVariableMapping(type, rawType);
+		if (targetType.isInterface()) {
+			// Look for superinterfaces that extend the target interface
+			Class<?>[] interfaces = rawType.getInterfaces();
+			for (int i = 0; i < interfaces.length; i++) {
+				if (Collection.class.isAssignableFrom(interfaces[i])) {
+					Type genericInterface = rawType.getGenericInterfaces()[i];
+					Type mappedInterface = getMappedType(genericInterface, varMapping);
+					return getElementTypes(mappedInterface, interfaces[i], targetType);
+				}
+			}
+		}
+		if (!rawType.isInterface()) {
+			// Visit the superclass if it extends the target class / implements the target interface
+			Class<?> rawSupertype = rawType.getSuperclass();
+			if (targetType.isAssignableFrom(rawSupertype)) {
+				Type genericSuperclass = rawType.getGenericSuperclass();
+				Type mappedSuperclass = getMappedType(genericSuperclass, varMapping);
+				return getElementTypes(mappedSuperclass, rawSupertype, targetType);
+			}
+		}
+		// No luck, return an array of Object types
+		Type[] result = new Type[targetType.getTypeParameters().length];
+		Arrays.fill(result, Object.class);
+		return result;
+	}
+	
+	private static <T> Map<String, Type> createVariableMapping(Type type, Class<T> rawType) {
+		if (type instanceof ParameterizedType) {
+			TypeVariable<Class<T>>[] vars = rawType.getTypeParameters();
+			Type[] args = ((ParameterizedType) type).getActualTypeArguments();
+			Map<String, Type> newVarMapping = new HashMap<>(capacity(vars.length));
+			for (int i = 0; i < vars.length; i++) {
+				Type actualType = Object.class;
+				if (i < args.length) {
+					actualType = args[i];
+					if (actualType instanceof WildcardType)
+						actualType = ((WildcardType) actualType).getUpperBounds()[0];
+				}
+				newVarMapping.put(vars[i].getName(), actualType);
+			}
+			return newVarMapping;
+		}
+		return Collections.emptyMap();
+	}
+	
+	private static int capacity(int expectedSize) {
+		if (expectedSize < 3)
+			return expectedSize + 1;
+		else
+			return expectedSize + expectedSize / 3;
+	}
+	
+	private static Type getMappedType(Type type, Map<String, Type> varMapping) {
+		if (type instanceof TypeVariable) {
+			String name = ((TypeVariable<?>) type).getName();
+			if (varMapping.containsKey(name))
+				return varMapping.get(name);
+		}
+		if (type instanceof WildcardType) {
+			return getMappedType(((WildcardType) type).getUpperBounds()[0], varMapping);
+		}
+		if (type instanceof ParameterizedType) {
+			ParameterizedType pt = (ParameterizedType) type;
+			Type[] origArgs = pt.getActualTypeArguments();
+			Type[] mappedArgs = new Type[origArgs.length];
+			for (int i = 0; i < origArgs.length; i++) {
+				mappedArgs[i] = getMappedType(origArgs[i], varMapping);
+			}
+			return new ParameterizedTypeImpl(pt, mappedArgs);
+		}
+		return type;
+	}
+
+	private static class ParameterizedTypeImpl implements ParameterizedType {
+		
+		private final Type ownerType;
+		private final Type rawType;
+		private final Type[] actualTypeArguments;
+		
+		ParameterizedTypeImpl(ParameterizedType original, Type[] typeArguments) {
+			this(original.getOwnerType(), original.getRawType(), typeArguments);
+		}
+		
+		ParameterizedTypeImpl(Type ownerType, Type rawType, Type[] typeArguments) {
+			this.ownerType = ownerType;
+			this.rawType = rawType;
+			this.actualTypeArguments = typeArguments;
+		}
+		
+		@Override
+		public Type getOwnerType() {
+			return ownerType;
+		}
+		
+		@Override
+		public Type getRawType() {
+			return rawType;
+		}
+
+		@Override
+		public Type[] getActualTypeArguments() {
+			return actualTypeArguments;
+		}
+		
+		@Override
+		public String toString() {
+			StringBuilder result = new StringBuilder();
+			if (ownerType != null) {
+				result.append(toString(ownerType));
+				result.append('$');
+			}
+			result.append(toString(rawType));
+			result.append('<');
+			for (int i = 0; i < actualTypeArguments.length; i++) {
+				if (i > 0)
+					result.append(", ");
+				result.append(toString(actualTypeArguments[i]));
+			}
+			result.append('>');
+			return result.toString();
+		}
+		
+		private String toString(Type type) {
+			if (type instanceof Class<?>)
+				return ((Class<?>) type).getName();
+			else
+				return String.valueOf(type);
+		}
+		
+	}
+	
+	/**
+	 * Return all possible types that can be expected when an element of the given type is parsed.
+	 * If the type satisfies {@link #isEither(Type)}, a list of the corresponding type arguments is returned,
+	 * otherwise a list containg the type itself is returned. Type parameters are <em>not</em> resolved
+	 * by this method (use {@link #getElementTypes(TypeToken, Class)} to get resolved parameters).
+	 */
+	public static Collection<Type> getExpectedTypes(Type type) {
+		Collection<Type> result = new ArrayList<>();
+		collectExpectedTypes(type, result);
+		return result;
+	}
+
+	private static void collectExpectedTypes(Type type, Collection<Type> types) {
+		if (isEither(type)) {
+			if (type instanceof ParameterizedType) {
+				for (Type typeArgument : ((ParameterizedType) type).getActualTypeArguments()) {
+					collectExpectedTypes(typeArgument, types);
+				}
+			}
+			if (type instanceof Class) {
+				for (Type typeParameter : ((Class<?>) type).getTypeParameters()) {
+					collectExpectedTypes(typeParameter, types);
+				}
+			}
+		} else {
+			types.add(type);
+		}
+	}
+
+	/**
+	 * Test whether the given type is Either.
+	 */
+	public static boolean isEither(Type type) {
+		if (type instanceof ParameterizedType) {
+			return isEither(((ParameterizedType) type).getRawType());
+		}
+		if (type instanceof Class) {
+			return Either.class.isAssignableFrom((Class<?>) type);
+		}
+		return false;
+	}
+	
+	/**
+	 * Test whether the given type is a two-tuple (pair).
+	 */
+	public static boolean isTwoTuple(Type type) {
+		if (type instanceof ParameterizedType) {
+			return isTwoTuple(((ParameterizedType) type).getRawType());
+		}
+		if (type instanceof Class) {
+			return Tuple.Two.class.isAssignableFrom((Class<?>) type);
+		}
+		return false;
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/messages/CancelParams.java b/java/org/eclipse/lsp4j/jsonrpc/messages/CancelParams.java
new file mode 100644
index 0000000..2c6a35f
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/messages/CancelParams.java
@@ -0,0 +1,86 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.messages;
+
+import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+
+/**
+ * To cancel a request a notification message with the following properties is sent.
+ */
+public class CancelParams {
+	
+	/**
+	 * The request id to cancel.
+	 */
+	@NonNull
+	private Either<String, Number> id;
+
+	@NonNull
+	public String getId() {
+		if (id == null)
+			return null;
+		if (id.isLeft())
+			return id.getLeft();
+		if (id.isRight())
+			return id.getRight().toString();
+		return null;
+	}
+	
+	@NonNull
+	public Either<String, Number> getRawId() {
+		return id;
+	}
+
+	public void setId(@NonNull String id) {
+		this.id = Either.forLeft(id);
+	}
+	
+	public void setId(@NonNull int id) {
+		this.id = Either.forRight(id);
+	}
+	
+	public void setRawId(@NonNull Either<String, Number> id) {
+		this.id = id;
+	}
+	
+	@Override
+	public String toString() {
+		return MessageJsonHandler.toString(this);
+	}
+
+	@Override
+	public boolean equals(final Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		CancelParams other = (CancelParams) obj;
+		if (this.id == null) {
+			if (other.id != null)
+				return false;
+		} else if (!this.id.equals(other.id))
+			return false;
+		return true;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((this.id == null) ? 0 : this.id.hashCode());
+		return result;
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/messages/Either.java b/java/org/eclipse/lsp4j/jsonrpc/messages/Either.java
new file mode 100644
index 0000000..0b5f484
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/messages/Either.java
@@ -0,0 +1,223 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.messages;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.function.Function;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+
+/**
+ * An either type maps union types in protocol specifications.
+ */
+public class Either<L, R> {
+
+	public static <L, R> Either<L, R> forLeft(@NonNull L left) {
+		return new Either<>(left, null);
+	}
+
+	public static <L, R> Either<L, R> forRight(@NonNull R right) {
+		return new Either<>(null, right);
+	}
+
+	private final L left;
+	private final R right;
+
+	protected Either(L left, R right) {
+		super();
+		this.left = left;
+		this.right = right;
+	}
+
+	public L getLeft() {
+		return left;
+	}
+
+	public R getRight() {
+		return right;
+	}
+	
+	public Object get() {
+		if (left != null)
+			return left;
+		if (right != null)
+			return right;
+		return null;
+	}
+
+	public boolean isLeft() {
+		return left != null;
+	}
+
+	public boolean isRight() {
+		return right != null;
+	}
+
+	public <T> T map(
+			@NonNull Function<? super L, ? extends T> mapLeft,
+			@NonNull Function<? super R, ? extends T> mapRight) {
+		if (isLeft()) {
+			return mapLeft.apply(getLeft());
+		}
+		if (isRight()) {
+			return mapRight.apply(getRight());
+		}
+		return null;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (obj instanceof Either<?, ?>) {
+			Either<?, ?> other = (Either<?, ?>) obj;
+			return (this.left == other.left && this.right == other.right)
+				|| (this.left != null && other.left != null && this.left.equals(other.left))
+				|| (this.right != null && other.right != null && this.right.equals(other.right));
+		}
+		return false;
+	}
+	
+	@Override
+	public int hashCode() {
+		if (this.left != null)
+			return this.left.hashCode();
+		if (this.right != null)
+			return this.right.hashCode();
+		return 0;
+	}
+
+	public String toString() {
+		StringBuilder builder = new StringBuilder("Either [").append(System.lineSeparator());
+		builder.append("  left = ").append(left).append(System.lineSeparator());
+		builder.append("  right = ").append(right).append(System.lineSeparator());
+		return builder.append("]").toString();
+	}
+
+	/**
+	 * Return a left disjoint type if the given type is either.
+	 * 
+	 * @deprecated Use {@link org.eclipse.lsp4j.jsonrpc.json.adapters.TypeUtils#getElementTypes(Type, Class, Class)} instead
+	 */
+	@Deprecated
+	public static Type getLeftDisjointType(Type type) {
+		if (isEither(type)) {
+			if (type instanceof ParameterizedType) {
+				final ParameterizedType parameterizedType = (ParameterizedType) type;
+				return parameterizedType.getActualTypeArguments()[0];
+			}
+			if (type instanceof Class) {
+				final Class<?> cls = (Class<?>) type;
+				return cls.getTypeParameters()[0];
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Return a right disjoint type if the given type is either.
+	 * 
+	 * @deprecated Use {@link org.eclipse.lsp4j.jsonrpc.json.adapters.TypeUtils#getElementTypes(Type, Class, Class)} instead
+	 */
+	@Deprecated
+	public static Type getRightDisjointType(Type type) {
+		if (isEither(type)) {
+			if (type instanceof ParameterizedType) {
+				final ParameterizedType parameterizedType = (ParameterizedType) type;
+				return parameterizedType.getActualTypeArguments()[1];
+			}
+			if (type instanceof Class) {
+				final Class<?> cls = (Class<?>) type;
+				return cls.getTypeParameters()[1];
+			}
+		}
+		return null;
+	}
+	
+	/**
+	 * Return all disjoint types.
+	 * 
+	 * @deprecated Use {@link org.eclipse.lsp4j.jsonrpc.json.adapters.TypeUtils#getExpectedTypes(Type)} instead
+	 */
+	@Deprecated
+	public static Collection<Type> getAllDisjoinTypes(Type type) {
+		return collectDisjoinTypes(type, new ArrayList<>());
+	}
+
+	@Deprecated
+	protected static Collection<Type> collectDisjoinTypes(Type type, Collection<Type> types) {
+		if (isEither(type)) {
+			if (type instanceof ParameterizedType) {
+				return collectDisjoinTypes((ParameterizedType) type, types);
+			}
+			if (type instanceof Class) {
+				return collectDisjoinTypes((Class<?>) type, types);
+			}
+		}
+		types.add(type);
+		return types;
+	}
+
+	@Deprecated
+	protected static Collection<Type> collectDisjoinTypes(ParameterizedType type, Collection<Type> types) {
+		for (Type typeArgument : type.getActualTypeArguments()) {
+			collectDisjoinTypes(typeArgument, types);
+		}
+		return types;
+	}
+
+	@Deprecated
+	protected static Collection<Type> collectDisjoinTypes(Class<?> type, Collection<Type> types) {
+		for (Type typeParameter : type.getTypeParameters()) {
+			collectDisjoinTypes(typeParameter, types);
+		}
+		return types;
+	}
+
+	/**
+	 * Test whether the given type is Either.
+	 * 
+	 * @deprecated Use {@link org.eclipse.lsp4j.jsonrpc.json.adapters.TypeUtils#isEither(Type)} instead
+	 */
+	@Deprecated
+	public static boolean isEither(Type type) {
+		if (type instanceof ParameterizedType) {
+			return isEither((ParameterizedType) type);
+		}
+		if (type instanceof Class) {
+			return isEither((Class<?>) type);
+		}
+		return false;
+	}
+
+	/**
+	 * Test whether the given type is Either.
+	 * 
+	 * @deprecated Use {@link org.eclipse.lsp4j.jsonrpc.json.adapters.TypeUtils#isEither(Type)} instead
+	 */
+	@Deprecated
+	public static boolean isEither(ParameterizedType type) {
+		return isEither(type.getRawType());
+	}
+
+	/**
+	 * Test whether the given class is Either.
+	 * 
+	 * @deprecated Use {@link org.eclipse.lsp4j.jsonrpc.json.adapters.TypeUtils#isEither(Type)} instead
+	 */
+	@Deprecated
+	public static boolean isEither(Class<?> cls) {
+		return Either.class.isAssignableFrom(cls);
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/messages/Either3.java b/java/org/eclipse/lsp4j/jsonrpc/messages/Either3.java
new file mode 100644
index 0000000..81f385e
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/messages/Either3.java
@@ -0,0 +1,111 @@
+/******************************************************************************
+ * Copyright (c) 2017 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.messages;
+
+import java.util.function.Function;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+
+/**
+ * Union type for three types.
+ */
+public class Either3<T1, T2, T3> extends Either<T1, Either<T2, T3>> {
+	
+	public static <T1, T2, T3> Either3<T1, T2, T3> forFirst(@NonNull T1 first) {
+		return new Either3<T1, T2, T3>(first, null);
+	}
+
+	public static <T1, T2, T3> Either3<T1, T2, T3> forSecond(@NonNull T2 second) {
+		return new Either3<T1, T2, T3>(null, new Either<T2, T3>(second, null));
+	}
+	
+	public static <T1, T2, T3> Either3<T1, T2, T3> forThird(@NonNull T3 third) {
+		return new Either3<T1, T2, T3>(null, new Either<T2, T3>(null, third));
+	}
+	
+	public static <T1, T2, T3> Either3<T1, T2, T3> forLeft3(@NonNull T1 first) {
+		return new Either3<T1, T2, T3>(first, null);
+	}
+	
+	public static <T1, T2, T3> Either3<T1, T2, T3> forRight3(@NonNull Either<T2, T3> right) {
+		return new Either3<T1, T2, T3>(null, right);
+	}
+
+	protected Either3(T1 left, Either<T2, T3> right) {
+		super(left, right);
+	}
+	
+	public T1 getFirst() {
+		return getLeft();
+	}
+	
+	public T2 getSecond() {
+		Either<T2, T3> right = getRight();
+		if (right == null)
+			return null;
+		else
+			return right.getLeft();
+	}
+	
+	public T3 getThird() {
+		Either<T2, T3> right = getRight();
+		if (right == null)
+			return null;
+		else
+			return right.getRight();
+	}
+	
+	@Override
+	public Object get() {
+		if (isRight())
+			return getRight().get();
+		return super.get();
+	}
+	
+	public boolean isFirst() {
+		return isLeft();
+	}
+	
+	public boolean isSecond() {
+		return isRight() && getRight().isLeft();
+	}
+	
+	public boolean isThird() {
+		return isRight() && getRight().isRight();
+	}
+
+	public <T> T map(
+			@NonNull Function<? super T1, ? extends T> mapFirst,
+			@NonNull Function<? super T2, ? extends T> mapSecond,
+			@NonNull Function<? super T3, ? extends T> mapThird) {
+		if (isFirst()) {
+			return mapFirst.apply(getFirst());
+		}
+		if (isSecond()) {
+			return mapSecond.apply(getSecond());
+		}
+		if (isThird()) {
+			return mapThird.apply(getThird());
+		}
+		return null;
+	}
+
+	@Override
+	public String toString() {
+		StringBuilder builder = new StringBuilder("Either3 [").append(System.lineSeparator());
+		builder.append("  first = ").append(getFirst()).append(System.lineSeparator());
+		builder.append("  second = ").append(getSecond()).append(System.lineSeparator());
+		builder.append("  third = ").append(getThird()).append(System.lineSeparator());
+		return builder.append("]").toString();
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/messages/IdentifiableMessage.java b/java/org/eclipse/lsp4j/jsonrpc/messages/IdentifiableMessage.java
new file mode 100644
index 0000000..61faf65
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/messages/IdentifiableMessage.java
@@ -0,0 +1,81 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.messages;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+
+/**
+ * A message with an {@code id} property.
+ */
+public abstract class IdentifiableMessage extends Message {
+	
+	/**
+	 * The message identifier.
+	 */
+	@NonNull
+	private Either<String, Number> id;
+
+	public String getId() {
+		if (id == null)
+			return null;
+		if (id.isLeft())
+			return id.getLeft();
+		if (id.isRight())
+			return id.getRight().toString();
+		return null;
+	}
+	
+	@NonNull
+	public Either<String, Number> getRawId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = Either.forLeft(id);
+	}
+	
+	public void setId(int id) {
+		this.id = Either.forRight(id);
+	}
+	
+	public void setRawId(@NonNull Either<String, Number> id) {
+		this.id = id;
+	}
+
+	@Override
+	public boolean equals(final Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		if (!super.equals(obj))
+			return false;
+		IdentifiableMessage other = (IdentifiableMessage) obj;
+		if (this.id == null) {
+			if (other.id != null)
+				return false;
+		} else if (!this.id.equals(other.id))
+			return false;
+		return true;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = super.hashCode();
+		result = prime * result + ((this.id == null) ? 0 : this.id.hashCode());
+		return result;
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/messages/Message.java b/java/org/eclipse/lsp4j/jsonrpc/messages/Message.java
new file mode 100644
index 0000000..5d4be74
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/messages/Message.java
@@ -0,0 +1,66 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.messages;
+
+import org.eclipse.lsp4j.jsonrpc.json.MessageConstants;
+import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+
+/**
+ * A general message as defined by JSON-RPC. The language server protocol always
+ * uses "2.0" as the jsonrpc version.
+ */
+public abstract class Message {
+
+	@NonNull
+	private String jsonrpc = MessageConstants.JSONRPC_VERSION;
+
+	@NonNull
+	public String getJsonrpc() {
+		return this.jsonrpc;
+	}
+
+	public void setJsonrpc(@NonNull String jsonrpc) {
+		this.jsonrpc = jsonrpc;
+	}
+	
+	@Override
+	public String toString() {
+		return MessageJsonHandler.toString(this);
+	}
+
+	@Override
+	public boolean equals(final Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		Message other = (Message) obj;
+		if (this.jsonrpc == null) {
+			if (other.jsonrpc != null)
+				return false;
+		} else if (!this.jsonrpc.equals(other.jsonrpc))
+			return false;
+		return true;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((this.jsonrpc == null) ? 0 : this.jsonrpc.hashCode());
+		return result;
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/messages/MessageIssue.java b/java/org/eclipse/lsp4j/jsonrpc/messages/MessageIssue.java
new file mode 100644
index 0000000..1220255
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/messages/MessageIssue.java
@@ -0,0 +1,60 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.messages;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+
+/**
+ * Describes an issue found while parsing or validating a message.
+ */
+public class MessageIssue {
+
+	@NonNull
+	private String text;
+
+	private int code;
+	
+	private Exception cause;
+	
+	public MessageIssue(@NonNull String text) {
+		this(text, 0, null);
+	}
+
+	public MessageIssue(@NonNull String text, int code) {
+		this(text, code, null);
+	}
+	
+	public MessageIssue(@NonNull String text, int code, Exception cause) {
+		this.text = text;
+		this.code = code;
+		this.cause = cause;
+	}
+	
+	@NonNull
+	public String getText() {
+		return text;
+	}
+	
+	public int getIssueCode() {
+		return code;
+	}
+
+	public Exception getCause() {
+		return cause;
+	}
+	
+	@Override
+	public String toString() {
+		return getText();
+	}
+	
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/messages/NotificationMessage.java b/java/org/eclipse/lsp4j/jsonrpc/messages/NotificationMessage.java
new file mode 100644
index 0000000..b10f9d4
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/messages/NotificationMessage.java
@@ -0,0 +1,83 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.messages;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+
+/**
+ * A notification message. A processed notification message must not send a
+ * response back. They work like events.
+ */
+public class NotificationMessage extends Message {
+
+	/**
+	 * The method to be invoked.
+	 */
+	@NonNull
+	private String method;
+
+	@NonNull
+	public String getMethod() {
+		return this.method;
+	}
+
+	public void setMethod(@NonNull String method) {
+		this.method = method;
+	}
+
+	/**
+	 * The method's params.
+	 */
+	private Object params;
+
+	public Object getParams() {
+		return this.params;
+	}
+
+	public void setParams(Object params) {
+		this.params = params;
+	}
+
+	@Override
+	public boolean equals(final Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		if (!super.equals(obj))
+			return false;
+		NotificationMessage other = (NotificationMessage) obj;
+		if (this.method == null) {
+			if (other.method != null)
+				return false;
+		} else if (!this.method.equals(other.method))
+			return false;
+		if (this.params == null) {
+			if (other.params != null)
+				return false;
+		} else if (!this.params.equals(other.params))
+			return false;
+		return true;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = super.hashCode();
+		result = prime * result + ((this.method == null) ? 0 : this.method.hashCode());
+		result = prime * result + ((this.params == null) ? 0 : this.params.hashCode());
+		return result;
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/messages/RequestMessage.java b/java/org/eclipse/lsp4j/jsonrpc/messages/RequestMessage.java
new file mode 100644
index 0000000..42d76c2
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/messages/RequestMessage.java
@@ -0,0 +1,84 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.messages;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+
+/**
+ * A request message to describe a request between the client and the server.
+ * Every processed request must send a response back to the sender of the
+ * request.
+ */
+public class RequestMessage extends IdentifiableMessage {
+
+	/**
+	 * The method to be invoked.
+	 */
+	@NonNull
+	private String method;
+
+	@NonNull
+	public String getMethod() {
+		return this.method;
+	}
+
+	public void setMethod(@NonNull String method) {
+		this.method = method;
+	}
+
+	/**
+	 * The method's parameters. The object type depends on the chosen method.
+	 */
+	private Object params;
+
+	public Object getParams() {
+		return this.params;
+	}
+
+	public void setParams(Object params) {
+		this.params = params;
+	}
+
+	@Override
+	public boolean equals(final Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		if (!super.equals(obj))
+			return false;
+		RequestMessage other = (RequestMessage) obj;
+		if (this.method == null) {
+			if (other.method != null)
+				return false;
+		} else if (!this.method.equals(other.method))
+			return false;
+		if (this.params == null) {
+			if (other.params != null)
+				return false;
+		} else if (!this.params.equals(other.params))
+			return false;
+		return true;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = super.hashCode();
+		result = prime * result + ((this.method == null) ? 0 : this.method.hashCode());
+		result = prime * result + ((this.params == null) ? 0 : this.params.hashCode());
+		return result;
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/messages/ResponseError.java b/java/org/eclipse/lsp4j/jsonrpc/messages/ResponseError.java
new file mode 100644
index 0000000..64b8888
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/messages/ResponseError.java
@@ -0,0 +1,123 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.messages;
+
+import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
+import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+
+import com.google.gson.annotations.JsonAdapter;
+
+public class ResponseError {
+
+	/**
+	 * A number indicating the error type that occurred.
+	 */
+	@NonNull
+	private int code;
+
+	@NonNull
+	public int getCode() {
+		return this.code;
+	}
+
+	public void setCode(@NonNull int code) {
+		this.code = code;
+	}
+
+	public void setCode(ResponseErrorCode code) {
+		this.setCode(code.getValue());
+	}
+
+	/**
+	 * A string providing a short description of the error.
+	 */
+	@NonNull
+	private String message;
+
+	@NonNull
+	public String getMessage() {
+		return this.message;
+	}
+
+	public void setMessage(@NonNull String message) {
+		this.message = message;
+	}
+
+	/**
+	 * A Primitive or Structured value that contains additional information
+	 * about the error. Can be omitted.
+	 */
+	@JsonAdapter(JsonElementTypeAdapter.Factory.class)
+	private Object data;
+
+	public Object getData() {
+		return this.data;
+	}
+
+	public void setData(Object data) {
+		this.data = data;
+	}
+
+	public ResponseError() {
+	}
+
+	public ResponseError(ResponseErrorCode code, String message, Object data) {
+		this(code.getValue(), message, data);
+	}
+
+	public ResponseError(int code, String message, Object data) {
+		this.code = code;
+		this.message = message;
+		this.data = data;
+	}
+
+	@Override
+	public String toString() {
+		return MessageJsonHandler.toString(this);
+	}
+
+	@Override
+	public boolean equals(final Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		ResponseError other = (ResponseError) obj;
+		if (other.code != this.code)
+			return false;
+		if (this.message == null) {
+			if (other.message != null)
+				return false;
+		} else if (!this.message.equals(other.message))
+			return false;
+		if (this.data == null) {
+			if (other.data != null)
+				return false;
+		} else if (!this.data.equals(other.data))
+			return false;
+		return true;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + this.code;
+		result = prime * result + ((this.message == null) ? 0 : this.message.hashCode());
+		result = prime * result + ((this.data == null) ? 0 : this.data.hashCode());
+		return result;
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/messages/ResponseErrorCode.java b/java/org/eclipse/lsp4j/jsonrpc/messages/ResponseErrorCode.java
new file mode 100644
index 0000000..2e86a42
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/messages/ResponseErrorCode.java
@@ -0,0 +1,110 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.messages;
+
+/**
+ * A number indicating the error type that occurred.
+ */
+public enum ResponseErrorCode {
+	
+	ParseError(-32700),
+	
+	InvalidRequest(-32600),
+	
+	MethodNotFound(-32601),
+	
+	InvalidParams(-32602),
+	
+	InternalError(-32603),
+	
+	/**
+	 * This is the start range of JSON RPC reserved error codes.
+	 * It doesn't denote a real error code. No LSP error codes should
+	 * be defined between the start and end range. For backwards
+	 * compatibility the {@link #serverNotInitialized} and the
+	 * {@link #UnknownErrorCode} are left in the range.
+	 *
+	 * Since 3.16.0
+	 */
+	jsonrpcReservedErrorRangeStart(-32099),
+	
+	/** @deprecated use {@link #jsonrpcReservedErrorRangeStart} */
+	@Deprecated
+	serverErrorStart(-32099),
+	
+	/**
+	 * Error code indicating that a server received a notification or
+	 * request before the server has received the {@code initialize} request.
+	 * 
+	 * Should be {@code ServerNotInitialized}
+	 */
+	serverNotInitialized(-32002),
+	
+	UnknownErrorCode(-32001),
+	
+	/**
+	 * This is the start range of JSON RPC reserved error codes.
+	 * It doesn't denote a real error code.
+	 * 
+	 * Since 3.16.0
+	 */
+	jsonrpcReservedErrorRangeEnd(-32000),
+	
+	/** @deprecated use {@link #jsonrpcReservedErrorRangeEnd} */
+	@Deprecated
+	serverErrorEnd(-32000),
+	
+	/**
+	 * This is the start range of LSP reserved error codes.
+	 * It doesn't denote a real error code.
+	 *
+	 * Since 3.16.0
+	 */
+	lspReservedErrorRangeStart(-32899),
+	
+	/**
+	 * The server detected that the content of a document got
+	 * modified outside normal conditions. A server should
+	 * NOT send this error code if it detects a content change
+	 * in it unprocessed messages. The result even computed
+	 * on an older state might still be useful for the client.
+	 *
+	 * If a client decides that a result is not of any use anymore
+	 * the client should cancel the request.
+	 */
+	ContentModified(-32801),
+	
+	/**
+	 * The client has canceled a request and a server as detected
+	 * the cancel.
+	 */
+	RequestCancelled(-32800),
+	
+	/**
+	 * This is the end range of LSP reserved error codes.
+	 * It doesn't denote a real error code.
+	 *
+	 * Since 3.16.0
+	 */
+	lspReservedErrorRangeEnd(-32800);
+	
+	private final int value;
+	
+	ResponseErrorCode(int value) {
+		this.value = value;
+	}
+	
+	public int getValue() {
+		return value;
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/messages/ResponseMessage.java b/java/org/eclipse/lsp4j/jsonrpc/messages/ResponseMessage.java
new file mode 100644
index 0000000..baf33e3
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/messages/ResponseMessage.java
@@ -0,0 +1,83 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.messages;
+
+/**
+ * Response message sent as a result of a request. If a request doesn't provide
+ * a result value the receiver of a request still needs to return a response
+ * message to conform to the JSON RPC specification. The result property of the
+ * ResponseMessage should be set to null in this case to signal a successful
+ * request. A response message is linked to a request via their {@code id} properties.
+ */
+public class ResponseMessage extends IdentifiableMessage {
+
+	/**
+	 * The result of a request. This can be omitted in the case of an error.
+	 * The object type depends on the method of the corresponding request.
+	 */
+	private Object result;
+
+	public Object getResult() {
+		return this.result;
+	}
+
+	public void setResult(Object result) {
+		this.result = result;
+	}
+
+	/**
+	 * The error object in case a request fails.
+	 */
+	private ResponseError error;
+
+	public ResponseError getError() {
+		return this.error;
+	}
+
+	public void setError(ResponseError error) {
+		this.error = error;
+	}
+
+	@Override
+	public boolean equals(final Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		if (!super.equals(obj))
+			return false;
+		ResponseMessage other = (ResponseMessage) obj;
+		if (this.result == null) {
+			if (other.result != null)
+				return false;
+		} else if (!this.result.equals(other.result))
+			return false;
+		if (this.error == null) {
+			if (other.error != null)
+				return false;
+		} else if (!this.error.equals(other.error))
+			return false;
+		return true;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = super.hashCode();
+		result = prime * result + ((this.result == null) ? 0 : this.result.hashCode());
+		result = prime * result + ((this.error == null) ? 0 : this.error.hashCode());
+		return result;
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/messages/Tuple.java b/java/org/eclipse/lsp4j/jsonrpc/messages/Tuple.java
new file mode 100644
index 0000000..03618ce
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/messages/Tuple.java
@@ -0,0 +1,81 @@
+package org.eclipse.lsp4j.jsonrpc.messages;
+
+import java.io.IOException;
+
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+
+/**
+ * Representation of tuple types.
+ */
+@SuppressWarnings("all")
+public interface Tuple {
+
+	public static <F, S> Two<F, S> two(F first, S second) {
+		return new Two<F, S>(first, second);
+	}
+	
+	/**
+	 * A two-tuple, i.e. a pair.
+	 */
+	public static class Two<F extends Object, S extends Object> implements Tuple {
+		
+		private final F first;
+		private final S second;
+
+		public Two(F first, S second) {
+			this.first = first;
+			this.second = second;
+		}
+
+		public F getFirst() {
+			return this.first;
+		}
+
+		public S getSecond() {
+			return this.second;
+		}
+
+		@Override
+		public boolean equals(final Object obj) {
+			if (this == obj)
+				return true;
+			if (obj == null)
+				return false;
+			if (getClass() != obj.getClass())
+				return false;
+			Tuple.Two<?, ?> other = (Tuple.Two<?, ?>) obj;
+			if (this.first == null) {
+				if (other.first != null)
+					return false;
+			} else if (!this.first.equals(other.first))
+				return false;
+			if (this.second == null) {
+				if (other.second != null)
+					return false;
+			} else if (!this.second.equals(other.second))
+				return false;
+			return true;
+		}
+
+		@Override
+		public int hashCode() {
+			final int prime = 31;
+			int result = 1;
+			result = prime * result + ((this.first == null) ? 0 : this.first.hashCode());
+			return prime * result + ((this.second == null) ? 0 : this.second.hashCode());
+		}
+
+		@Override
+		public String toString() {
+			StringBuilder builder = new StringBuilder("Tuples.Two [").append(System.lineSeparator());
+			builder.append("  first = ").append(first).append(System.lineSeparator());
+			builder.append("  second = ").append(second).append(System.lineSeparator());
+			return builder.append("]").toString();
+		}
+	}
+	
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/services/AnnotationUtil.java b/java/org/eclipse/lsp4j/jsonrpc/services/AnnotationUtil.java
new file mode 100644
index 0000000..48f6fc2
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/services/AnnotationUtil.java
@@ -0,0 +1,131 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.services;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.function.Consumer;
+
+public final class AnnotationUtil {
+	private AnnotationUtil() {}
+	
+	public static void findDelegateSegments(Class<?> clazz, Set<Class<?>> visited, Consumer<Method> acceptor) {
+		if (clazz == null || !visited.add(clazz))
+			return;
+		findDelegateSegments(clazz.getSuperclass(), visited, acceptor);
+		for (Class<?> interf : clazz.getInterfaces()) {
+			findDelegateSegments(interf, visited, acceptor);
+		}
+		for (Method method : clazz.getDeclaredMethods()) {
+			if (isDelegateMethod(method)) {
+				acceptor.accept(method);
+			}
+		}
+	}
+
+	public static boolean isDelegateMethod(Method method) {
+		if (!method.isSynthetic()) {
+			JsonDelegate jsonDelegate = method.getAnnotation(JsonDelegate.class);
+			if (jsonDelegate != null) {
+				if (!(method.getParameterCount() == 0 && method.getReturnType().isInterface())) {
+					throw new IllegalStateException(
+							"The method " + method.toString() + " is not a proper @JsonDelegate method.");
+				}
+				return true;
+			}
+		}
+		return false;
+	}
+	
+
+	/**
+	 * Depth first search for annotated methods in hierarchy.
+	 */
+	public static void findRpcMethods(Class<?> clazz, Set<Class<?>> visited, Consumer<MethodInfo> acceptor) {
+		if (clazz == null || !visited.add(clazz))
+			return;
+		findRpcMethods(clazz.getSuperclass(), visited, acceptor);
+		for (Class<?> interf : clazz.getInterfaces()) {
+			findRpcMethods(interf, visited, acceptor);
+		}
+		String segment = getSegment(clazz);
+		for (Method method : clazz.getDeclaredMethods()) {
+			MethodInfo methodInfo = createMethodInfo(method, segment);
+			if (methodInfo != null) {
+				acceptor.accept(methodInfo);
+			}
+		}
+	}
+
+	protected static String getSegment(Class<?> clazz) {
+		JsonSegment jsonSegment = clazz.getAnnotation(JsonSegment.class);
+		return jsonSegment == null ? "" : jsonSegment.value() + "/";
+	}
+	
+	protected static MethodInfo createMethodInfo(Method method, String segment) {
+		if (!method.isSynthetic()) {
+			JsonRequest jsonRequest = method.getAnnotation(JsonRequest.class);
+			if (jsonRequest != null) {
+				return createRequestInfo(method, segment, jsonRequest);
+			}
+			JsonNotification jsonNotification = method.getAnnotation(JsonNotification.class);
+			if (jsonNotification != null) {
+				return createNotificationInfo(method, segment, jsonNotification);
+			}
+		}
+		return null;
+	}
+
+	protected static MethodInfo createNotificationInfo(Method method, String segment, JsonNotification jsonNotification) {
+		MethodInfo methodInfo = createMethodInfo(method, jsonNotification.useSegment(), segment, jsonNotification.value());
+		methodInfo.isNotification = true;
+		return methodInfo;
+	}
+	
+	protected static MethodInfo createRequestInfo(Method method, String segment, JsonRequest jsonRequest) {
+		return createMethodInfo(method, jsonRequest.useSegment(), segment, jsonRequest.value());
+	}
+	
+	protected static MethodInfo createMethodInfo(Method method, boolean useSegment, String segment, String value) {
+		method.setAccessible(true);
+
+		MethodInfo methodInfo = new MethodInfo();
+		methodInfo.method = method;
+		methodInfo.parameterTypes = getParameterTypes(method);
+		methodInfo.name = getMethodName(method, useSegment, segment, value);
+		return methodInfo;
+	}
+	
+	protected static String getMethodName(Method method, boolean useSegment, String segment, String value) {
+		String name = value != null && value.length() > 0 ? value : method.getName();
+		return useSegment ? segment + name : name;
+	}
+
+	protected static Type[] getParameterTypes(Method method) {
+		return Arrays.stream(method.getParameters()).map(t -> t.getParameterizedType()).toArray(Type[]::new);
+	}
+	
+	static class MethodInfo {
+		private static Type[] EMPTY_TYPE_ARRAY = {};
+		public String name;
+		public Method method;
+		public Type[] parameterTypes = EMPTY_TYPE_ARRAY;
+		public boolean isNotification = false;
+	}
+
+	static class DelegateInfo {
+		public Method method;
+		public Object delegate;
+	}
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/services/EndpointProxy.java b/java/org/eclipse/lsp4j/jsonrpc/services/EndpointProxy.java
new file mode 100644
index 0000000..bb1609c
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/services/EndpointProxy.java
@@ -0,0 +1,130 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.services;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+
+import org.eclipse.lsp4j.jsonrpc.Endpoint;
+import org.eclipse.lsp4j.jsonrpc.services.AnnotationUtil.DelegateInfo;
+import org.eclipse.lsp4j.jsonrpc.services.AnnotationUtil.MethodInfo;
+
+/**
+ * A Proxy that wraps an {@link Endpoint} in one or more service interfaces, i.e. interfaces
+ * containing {@link JsonNotification} and {@link JsonRequest} methods.
+ */
+public class EndpointProxy implements InvocationHandler {
+	
+	private final Method object_equals;
+	private final Method object_hashCode;
+	private final Method object_toString;
+
+	private final Endpoint delegate;
+	private final LinkedHashMap<String, MethodInfo> methodInfos;
+	private final LinkedHashMap<String, DelegateInfo> delegatedSegments;
+
+	public EndpointProxy(Endpoint delegate, Class<?> interface_) {
+		this(delegate, Collections.singletonList(interface_));
+	}
+	
+	public EndpointProxy(Endpoint delegate, Collection<Class<?>> interfaces) {
+		if (delegate == null)
+			throw new NullPointerException("delegate");
+		if (interfaces == null)
+			throw new NullPointerException("interfaces");
+		if (interfaces.isEmpty())
+			throw new IllegalArgumentException("interfaces must not be empty.");
+		
+		this.delegate = delegate;
+		try {
+			object_equals = Object.class.getDeclaredMethod("equals", Object.class);
+			object_hashCode = Object.class.getDeclaredMethod("hashCode");
+			object_toString = Object.class.getDeclaredMethod("toString");
+		} catch (NoSuchMethodException | SecurityException exception) {
+			throw new RuntimeException(exception);
+		}
+		methodInfos = new LinkedHashMap<>();
+		delegatedSegments = new LinkedHashMap<>();
+		for (Class<?> interf : interfaces) {
+			AnnotationUtil.findRpcMethods(interf, new HashSet<Class<?>>(), (methodInfo) -> {
+				if (methodInfos.put(methodInfo.method.getName(), methodInfo) != null) {
+					throw new IllegalStateException("Duplicate RPC method " + methodInfo.method);
+				}
+			});
+			AnnotationUtil.findDelegateSegments(interf, new HashSet<Class<?>>(), (method) -> {
+				Object delegateProxy = ServiceEndpoints.toServiceObject(delegate, method.getReturnType());
+				DelegateInfo info = new DelegateInfo();
+				info.delegate = delegateProxy;
+				info.method = method;
+				if (delegatedSegments.put(method.getName(), info) != null) {
+					throw new IllegalStateException("Duplicate RPC method " + method);
+				}
+			});
+		}
+	}
+
+	@Override
+	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+		args = args == null ? new Object[0] : args;
+		MethodInfo methodInfo = this.methodInfos.get(method.getName());
+		if (methodInfo != null) {
+			Object params = getParams(args, methodInfo);
+			if (methodInfo.isNotification) {
+				delegate.notify(methodInfo.name, params);
+				return null;
+			}
+			return delegate.request(methodInfo.name, params);
+		}
+		DelegateInfo delegateInfo = this.delegatedSegments.get(method.getName());
+		if (delegateInfo != null) {
+			return delegateInfo.delegate;
+		}
+		if (object_equals.equals(method) && args.length == 1) {
+			if(args[0] != null ) {
+				try {
+					return this.equals(Proxy.getInvocationHandler(args[0]));
+				} catch (IllegalArgumentException exception) {
+				}
+			}
+			return this.equals(args[0]);
+		}
+		if (object_hashCode.equals(method)) {
+			return this.hashCode();
+		}
+		if (object_toString.equals(method)) {
+			return this.toString();
+		}
+		return method.invoke(delegate, args);
+	}
+
+	protected Object getParams(Object[] args, MethodInfo methodInfo) {
+		if (args.length == 0) {
+			return null;
+		}
+		if (args.length == 1) {
+			return args[0];
+		}
+		return Arrays.asList(args);
+	}
+	
+	@Override
+	public String toString() {
+		return getClass().getSimpleName() + " for " + delegate.toString();
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/services/GenericEndpoint.java b/java/org/eclipse/lsp4j/jsonrpc/services/GenericEndpoint.java
new file mode 100644
index 0000000..918c0d8
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/services/GenericEndpoint.java
@@ -0,0 +1,180 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.services;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Function;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.stream.Stream;
+
+import org.eclipse.lsp4j.jsonrpc.Endpoint;
+import org.eclipse.lsp4j.jsonrpc.ResponseErrorException;
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseError;
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseErrorCode;
+
+/**
+ * An endpoint that reflectively delegates to {@link JsonNotification} and
+ * {@link JsonRequest} methods of one or more given delegate objects.
+ */
+public class GenericEndpoint implements Endpoint {
+	
+	private static final Logger LOG = Logger.getLogger(GenericEndpoint.class.getName());
+	private static final Object[] NO_ARGUMENTS = {};
+
+	private final LinkedHashMap<String, Function<Object, CompletableFuture<Object>>> methodHandlers = new LinkedHashMap<>();
+	private final List<Object> delegates;
+
+	public GenericEndpoint(Object delegate) {
+		this.delegates = Collections.singletonList(delegate);
+		recursiveFindRpcMethods(delegate, new HashSet<>(), new HashSet<>());
+	}
+	
+	public GenericEndpoint(Collection<Object> delegates) {
+		this.delegates = new ArrayList<>(delegates);
+		for (Object delegate : this.delegates) {
+			recursiveFindRpcMethods(delegate, new HashSet<>(), new HashSet<>());
+		}
+	}
+
+	protected void recursiveFindRpcMethods(Object current, Set<Class<?>> visited, Set<Class<?>> visitedForDelegate) {
+		AnnotationUtil.findRpcMethods(current.getClass(), visited, (methodInfo) -> {
+			@SuppressWarnings("unchecked")
+			Function<Object, CompletableFuture<Object>> handler = (arg) -> {
+				try {
+					Method method = methodInfo.method;
+					Object[] arguments = this.getArguments(method, arg);
+					return (CompletableFuture<Object>) method.invoke(current, arguments);
+				} catch (InvocationTargetException | IllegalAccessException e) {
+					throw new RuntimeException(e);
+				}
+			};
+			if (methodHandlers.put(methodInfo.name, handler) != null) {
+				throw new IllegalStateException("Multiple methods for name " + methodInfo.name);
+			}
+		});
+		AnnotationUtil.findDelegateSegments(current.getClass(), visitedForDelegate, (method) -> {
+			try {
+				Object delegate = method.invoke(current);
+				if (delegate != null) {
+					recursiveFindRpcMethods(delegate, visited, visitedForDelegate);
+				} else {
+					LOG.log(Level.SEVERE, "A delegate object is null, jsonrpc methods of '" + method + "' are ignored");
+				}
+			} catch (InvocationTargetException | IllegalAccessException e) {
+				throw new RuntimeException(e);
+			}
+		});
+	}
+	
+	protected Object[] getArguments(Method method, Object arg) {
+		int parameterCount = method.getParameterCount();
+		if (parameterCount == 0) {
+			if (arg != null) {
+				LOG.warning("Unexpected params '" + arg + "' for '" + method + "' is ignored");
+			}
+			return NO_ARGUMENTS;
+		}
+		if (arg instanceof List<?>) {
+			List<?> arguments = (List<?>) arg;
+			int argumentCount = arguments.size(); 
+			if (argumentCount == parameterCount) {
+				return arguments.toArray();
+			}
+			if (argumentCount > parameterCount) {
+				Stream<?> unexpectedArguments = arguments.stream().skip(parameterCount);
+				String unexpectedParams = unexpectedArguments.map(a -> "'" + a + "'").reduce((a, a2) -> a + ", " + a2).get();
+				LOG.warning("Unexpected params " + unexpectedParams + " for '" + method + "' is ignored");
+				return arguments.subList(0, parameterCount).toArray();
+			}
+			return arguments.toArray(new Object[parameterCount]);
+		}
+		Object[] arguments = new Object[parameterCount];
+		arguments[0] = arg;
+		return arguments;
+	}
+
+	@Override
+	public CompletableFuture<?> request(String method, Object parameter) {
+		// Check the registered method handlers
+		Function<Object, CompletableFuture<Object>> handler = methodHandlers.get(method);
+		if (handler != null) {
+			return handler.apply(parameter);
+		}
+		
+		// Ask the delegate objects whether they can handle the request generically
+		List<CompletableFuture<?>> futures = new ArrayList<>(delegates.size());
+		for (Object delegate : delegates) {
+			if (delegate instanceof Endpoint) {
+				futures.add(((Endpoint) delegate).request(method, parameter));
+			}
+		}
+		if (!futures.isEmpty()) {
+			return CompletableFuture.anyOf(futures.toArray(new CompletableFuture[futures.size()]));
+		}
+		
+		// Create a log message about the unsupported method
+		String message = "Unsupported request method: " + method;
+		if (isOptionalMethod(method)) {
+			LOG.log(Level.INFO, message);
+			return CompletableFuture.completedFuture(null);
+		}
+		LOG.log(Level.WARNING, message);
+		CompletableFuture<?> exceptionalResult = new CompletableFuture<Object>();
+		ResponseError error = new ResponseError(ResponseErrorCode.MethodNotFound, message, null);
+		exceptionalResult.completeExceptionally(new ResponseErrorException(error));
+		return exceptionalResult;
+	}
+
+	@Override
+	public void notify(String method, Object parameter) {
+		// Check the registered method handlers
+		Function<Object, CompletableFuture<Object>> handler = methodHandlers.get(method);
+		if (handler != null) {
+			handler.apply(parameter);
+			return;
+		}
+		
+		// Ask the delegate objects whether they can handle the notification generically
+		int notifiedDelegates = 0;
+		for (Object delegate : delegates) {
+			if (delegate instanceof Endpoint) {
+				((Endpoint) delegate).notify(method, parameter);
+				notifiedDelegates++;
+			}
+		}
+		
+		if (notifiedDelegates == 0) {
+			// Create a log message about the unsupported method
+			String message = "Unsupported notification method: " + method;
+			if (isOptionalMethod(method)) {
+				LOG.log(Level.INFO, message);
+			} else {
+				LOG.log(Level.WARNING, message);
+			}
+		}
+	}
+	
+	protected boolean isOptionalMethod(String method) {
+		return method != null && method.startsWith("$/");
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/services/JsonDelegate.java b/java/org/eclipse/lsp4j/jsonrpc/services/JsonDelegate.java
new file mode 100644
index 0000000..5a6b224
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/services/JsonDelegate.java
@@ -0,0 +1,28 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.services;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * A method annotated with {@link JsonDelegate} is treated as a delegate method.
+ * As a result jsonrpc methods of the delegate will be considered, too.
+ * If an annotated method returns `null`
+ * then jsonrpc methods of the delegate are not considered.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface JsonDelegate {
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/services/JsonNotification.java b/java/org/eclipse/lsp4j/jsonrpc/services/JsonNotification.java
new file mode 100644
index 0000000..75ad20b
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/services/JsonNotification.java
@@ -0,0 +1,52 @@
+/******************************************************************************
+ * Copyright (c) 2016, 2020 TypeFox and others.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.services;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to mark a notification method on an interface or class.
+ * <p>
+ * A notification method must be of type <code>void</code> and have zero or one
+ * argument.
+ * <p>
+ * According to jsonrpc an argument must be an 'object' (a java bean, not e,g.
+ * String).
+ * <p>
+ * The name of the jsonrpc notification will be the optional segment, followed
+ * by the name of the Java method that is annotated with JsonNotification. The
+ * name of the jsonrpc notification can be customized by using the
+ * {@link #value()} field of this annotation. To specify the whole name,
+ * including the segment, in the value, set {@link #useSegment()} to false.
+ *
+ * @see JsonSegment
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface JsonNotification {
+	/**
+	 * The name of the the jsonrpc request method. If empty, uses the name of the
+	 * annotated method.
+	 */
+	String value() default "";
+
+	/**
+	 * When using segments, useSegment will be true to prepend the segment name to
+	 * the name of the request.
+	 *
+	 * @see JsonSegment
+	 */
+	boolean useSegment() default true;
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/services/JsonRequest.java b/java/org/eclipse/lsp4j/jsonrpc/services/JsonRequest.java
new file mode 100644
index 0000000..4e9b801
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/services/JsonRequest.java
@@ -0,0 +1,53 @@
+/******************************************************************************
+ * Copyright (c) 2016, 2020 TypeFox and others.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.services;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * Annotation to mark a request method on an interface or class.
+ * <p>
+ * A request method must have the return type {@link CompletableFuture} with an
+ * object parameter type or Void and have zero or one argument.
+ * <p>
+ * According to jsonrpc an argument must be an 'object' (a java bean, not e,g.
+ * String).
+ * <p>
+ * The name of the jsonrpc request will be the optional segment, followed by the
+ * name of the Java method that is annotated with JsonRequest. The name of the
+ * jsonrpc request can be customized by using the {@link #value()} field of this
+ * annotation. To specify the whole name, including the segment, in the value,
+ * set {@link #useSegment()} to false.
+ *
+ * @see JsonSegment
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.METHOD, ElementType.TYPE })
+public @interface JsonRequest {
+	/**
+	 * The name of the the jsonrpc request method. If empty, uses the name of the
+	 * annotated method.
+	 */
+	String value() default "";
+
+	/**
+	 * When using segments, useSegment will be true to prepend the segment name to
+	 * the name of the request.
+	 *
+	 * @see JsonSegment
+	 */
+	boolean useSegment() default true;
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/services/JsonSegment.java b/java/org/eclipse/lsp4j/jsonrpc/services/JsonSegment.java
new file mode 100644
index 0000000..2b73197
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/services/JsonSegment.java
@@ -0,0 +1,26 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.services;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Use on a class or interface to prefix all declared {@link JsonRequest} and {@link JsonNotification} methods.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface JsonSegment {
+	String value() default "";
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/services/ServiceEndpoints.java b/java/org/eclipse/lsp4j/jsonrpc/services/ServiceEndpoints.java
new file mode 100644
index 0000000..c8ad3f0
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/services/ServiceEndpoints.java
@@ -0,0 +1,128 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.services;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.lsp4j.jsonrpc.Endpoint;
+import org.eclipse.lsp4j.jsonrpc.json.JsonRpcMethod;
+import org.eclipse.lsp4j.jsonrpc.json.ResponseJsonAdapter;
+
+import com.google.gson.TypeAdapterFactory;
+
+public final class ServiceEndpoints {
+	private ServiceEndpoints() {}
+	
+	/**
+	 * Wraps a given {@link Endpoint} in the given service interface.
+	 * 
+	 * @return the wrapped service object
+	 */
+	@SuppressWarnings("unchecked")
+	public static <T> T toServiceObject(Endpoint endpoint, Class<T> interface_) {
+		Class<?>[] interfArray = new Class[]{interface_, Endpoint.class};
+		EndpointProxy invocationHandler = new EndpointProxy(endpoint, interface_);
+		return (T) Proxy.newProxyInstance(interface_.getClassLoader(), interfArray, invocationHandler);
+	}
+	
+	/**
+	 * Wraps a given {@link Endpoint} in the given service interfaces.
+	 * 
+	 * @return the wrapped service object
+	 */
+	public static Object toServiceObject(Endpoint endpoint, Collection<Class<?>> interfaces, ClassLoader classLoader) {
+		Class<?>[] interfArray = new Class[interfaces.size() + 1];
+		interfaces.toArray(interfArray);
+		interfArray[interfArray.length - 1] = Endpoint.class;
+		EndpointProxy invocationHandler = new EndpointProxy(endpoint, interfaces);
+		return Proxy.newProxyInstance(classLoader, interfArray, invocationHandler);
+	}
+	
+	/**
+	 * Wraps a given object with service annotations behind an {@link Endpoint} interface.
+	 * 
+	 * @return the wrapped service endpoint
+	 */
+	public static Endpoint toEndpoint(Object serviceObject) {
+		return new GenericEndpoint(serviceObject);
+	}
+	
+	/**
+	 * Wraps a collection of objects with service annotations behind an {@link Endpoint} interface.
+	 * 
+	 * @return the wrapped service endpoint
+	 */
+	public static Endpoint toEndpoint(Collection<Object> serviceObjects) {
+		return new GenericEndpoint(serviceObjects);
+	}
+	
+	/**
+	 * Finds all Json RPC methods on a given class.
+	 * 
+	 * @return the supported JsonRpcMethods
+	 */
+	public static Map<String, JsonRpcMethod> getSupportedMethods(Class<?> type) {
+		Set<Class<?>> visitedTypes = new HashSet<>();
+		return getSupportedMethods(type, visitedTypes);
+	}
+	
+	/**
+	 * Finds all Json RPC methods on a given type
+	 */
+	private static Map<String, JsonRpcMethod> getSupportedMethods(Class<?> type, Set<Class<?>> visitedTypes) {
+		Map<String, JsonRpcMethod> result = new LinkedHashMap<String, JsonRpcMethod>();
+		AnnotationUtil.findRpcMethods(type, visitedTypes, (methodInfo) -> {
+			JsonRpcMethod meth;
+			if (methodInfo.isNotification) {
+				meth = JsonRpcMethod.notification(methodInfo.name, methodInfo.parameterTypes);
+			} else {
+				Type genericReturnType = methodInfo.method.getGenericReturnType();
+				if (genericReturnType instanceof ParameterizedType) {
+					Type returnType = ((ParameterizedType) genericReturnType).getActualTypeArguments()[0];
+					TypeAdapterFactory responseTypeAdapter = null;
+					ResponseJsonAdapter responseTypeAdapterAnnotation = methodInfo.method.getAnnotation(ResponseJsonAdapter.class);
+					if (responseTypeAdapterAnnotation != null) {
+						try {
+							responseTypeAdapter = responseTypeAdapterAnnotation.value().newInstance();
+						} catch (InstantiationException | IllegalAccessException e) {
+							throw new RuntimeException(e);
+						}
+					}
+					meth = JsonRpcMethod.request(methodInfo.name, returnType, responseTypeAdapter, methodInfo.parameterTypes);
+				} else {
+					throw new IllegalStateException("Expecting return type of CompletableFuture but was : " + genericReturnType);
+				}
+			}
+			if (result.put(methodInfo.name, meth) != null) {
+				throw new IllegalStateException("Duplicate RPC method "+methodInfo.name+".");
+			};
+		});
+		
+		AnnotationUtil.findDelegateSegments(type, new HashSet<>(), (method)-> {
+			Map<String, JsonRpcMethod> supportedDelegateMethods = getSupportedMethods(method.getReturnType(), visitedTypes);
+			for (JsonRpcMethod meth : supportedDelegateMethods.values()) {
+				if (result.put(meth.getMethodName(), meth) != null) {
+					throw new IllegalStateException("Duplicate RPC method "+meth.getMethodName()+".");
+				};
+			}
+		});
+		return result;
+	}
+	
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/validation/NonNull.java b/java/org/eclipse/lsp4j/jsonrpc/validation/NonNull.java
new file mode 100644
index 0000000..9771e75
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/validation/NonNull.java
@@ -0,0 +1,31 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.validation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Indicates that the annotated field or parameter must not be set to {@code null}. If validation
+ * is active, an exception is thrown when a message is received where a {@code NonNull} field
+ * has a {@code null} or {@code undefined} value.
+ * 
+ * In order to achieve consistent behavior, for every field with this annotation the corresponding
+ * getter method as well as the parameter of the corresponding setter method are also expected to
+ * be annotated.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE_PARAMETER})
+public @interface NonNull {
+}
diff --git a/java/org/eclipse/lsp4j/jsonrpc/validation/ReflectiveMessageValidator.java b/java/org/eclipse/lsp4j/jsonrpc/validation/ReflectiveMessageValidator.java
new file mode 100644
index 0000000..965c811
--- /dev/null
+++ b/java/org/eclipse/lsp4j/jsonrpc/validation/ReflectiveMessageValidator.java
@@ -0,0 +1,185 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.validation;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.eclipse.lsp4j.jsonrpc.JsonRpcException;
+import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
+import org.eclipse.lsp4j.jsonrpc.MessageIssueException;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.messages.Message;
+import org.eclipse.lsp4j.jsonrpc.messages.MessageIssue;
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseErrorCode;
+
+import com.google.gson.JsonElement;
+
+/**
+ * Validates messages and forwards them to other message consumers. In case an issue is found,
+ * a {@link MessageIssueException} is thrown.
+ */
+public class ReflectiveMessageValidator implements MessageConsumer {
+
+	private static final Logger LOG = Logger.getLogger(ReflectiveMessageValidator.class.getName());
+
+	private final MessageConsumer delegate;
+	
+	/**
+	 * When created with this constructor, the validator acts as a message sink.
+	 */
+	public ReflectiveMessageValidator() {
+		this.delegate = null;
+	}
+
+	/**
+	 * Forward messages to the given consumer unless an issue is found.
+	 */
+	public ReflectiveMessageValidator(MessageConsumer delegate) {
+		this.delegate = delegate;
+	}
+
+	@Override
+	public void consume(Message message) throws MessageIssueException, JsonRpcException {
+		List<MessageIssue> issues = validate(message);
+		if (!issues.isEmpty()) {
+			// Sort the messages in order to get a stable order (otherwise it depends on the JVM's reflection implementation)
+			Collections.sort(issues, (issue1, issue2) -> issue1.getText().compareTo(issue2.getText()));
+			throw new MessageIssueException(message, issues);
+		} else if (delegate != null) {
+			delegate.consume(message);
+		}
+	}
+	
+	/**
+	 * Check whether the given object is valid. If it is not valid, its issues are not reported.
+	 */
+	public boolean isValid(Object object) {
+		List<MessageIssue> issues = validate(object);
+		return issues.isEmpty();
+	}
+	
+	protected List<MessageIssue> validate(Object object) {
+		List<MessageIssue> result = new ArrayList<>();
+		try {
+			validate(object, result, new LinkedList<>(), new LinkedList<>());
+		} catch (Exception e) {
+			LOG.log(Level.SEVERE, "Error during message validation: " + e.getMessage(), e);
+			result.add(new MessageIssue("Message validation failed, please check the logs of the remote endpoint.",
+					ResponseErrorCode.InvalidParams.getValue()));
+		}
+		return result;
+	}
+	
+	/**
+	 * Validate all fields of the given object.
+	 */
+	protected void validate(Object object, List<MessageIssue> issues, Deque<Object> objectStack, Deque<Object> accessorStack) throws Exception {
+		if (object == null 
+				|| object instanceof Enum<?> 
+				|| object instanceof String 
+				|| object instanceof Number
+				|| object instanceof Boolean
+				|| object instanceof JsonElement
+				|| object instanceof Throwable) {
+			return;
+		}
+		if (objectStack.contains(object)) {
+			issues.add(new MessageIssue("An element of the message has a direct or indirect reference to itself."
+					+ " Path: " + createPathString(accessorStack),
+					ResponseErrorCode.InvalidParams.getValue()));
+			return;
+		}
+		objectStack.push(object);
+		if (object instanceof List<?>) {
+			ListIterator<?> iter = ((List<?>) object).listIterator();
+			while (iter.hasNext()) {
+				accessorStack.push(iter.nextIndex());
+				Object element = iter.next();
+				if (element == null) {
+					issues.add(new MessageIssue("Lists must not contain null references."
+							+ " Path: " + createPathString(accessorStack),
+							ResponseErrorCode.InvalidParams.getValue()));
+				}
+				validate(element, issues, objectStack, accessorStack);
+				accessorStack.pop();
+			}
+		} else if (object instanceof Either<?, ?>) {
+			Either<?, ?> either = (Either<?, ?>) object;
+			if (either.isLeft()) {
+				validate(either.getLeft(), issues, objectStack, accessorStack);
+			} else if (either.isRight()) {
+				validate(either.getRight(), issues, objectStack, accessorStack);
+			} else {
+				issues.add(new MessageIssue("An Either instance must not be empty."
+						 + " Path: " + createPathString(accessorStack),
+						ResponseErrorCode.InvalidParams.getValue()));
+			}
+		} else {
+			for (Method method : object.getClass().getMethods()) {
+				if (isGetter(method)) {
+					accessorStack.push(method);
+					Object value = method.invoke(object);
+					if (value == null && method.getAnnotation(NonNull.class) != null) {
+						issues.add(new MessageIssue("The accessor '" + method.getDeclaringClass().getSimpleName()
+								 + "." + method.getName() + "()' must return a non-null value."
+								 + " Path: " + createPathString(accessorStack),
+								ResponseErrorCode.InvalidParams.getValue()));
+					}
+					validate(value, issues, objectStack, accessorStack);
+					accessorStack.pop();
+				}
+			}
+		}
+		objectStack.pop();
+	}
+	
+	protected String createPathString(Deque<Object> accessorStack) {
+		StringBuilder result = new StringBuilder("$");
+		Iterator<Object> resultIter = accessorStack.descendingIterator();
+		while(resultIter.hasNext()) {
+			Object accessor = resultIter.next();
+			if (accessor instanceof Method)
+				result.append('.').append(getPropertyName((Method) accessor));
+			else if (accessor instanceof Integer)
+				result.append('[').append(accessor).append(']');
+			else
+				result.append(accessor);
+		}
+		return result.toString();
+	}
+
+	protected boolean isGetter(Method method) {
+		return method.getParameterCount() == 0 && method.getName().startsWith("get")
+				&& method.getDeclaringClass() != Object.class
+				&& Modifier.isPublic(method.getModifiers())
+				&& !Modifier.isStatic(method.getModifiers());
+	}
+	
+	protected String getPropertyName(Method method) {
+		String methodName = method.getName();
+		if (methodName.startsWith("get") && methodName.length() > 3)
+			return methodName.substring(3, 4).toLowerCase() + methodName.substring(4);
+		else
+			return methodName;
+	}
+	
+}
diff --git a/java/org/eclipse/lsp4j/launch/LSPLauncher.java b/java/org/eclipse/lsp4j/launch/LSPLauncher.java
new file mode 100644
index 0000000..88229d2
--- /dev/null
+++ b/java/org/eclipse/lsp4j/launch/LSPLauncher.java
@@ -0,0 +1,160 @@
+/******************************************************************************
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.launch;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.concurrent.ExecutorService;
+import java.util.function.Function;
+
+import org.eclipse.lsp4j.jsonrpc.Launcher;
+import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
+import org.eclipse.lsp4j.jsonrpc.validation.ReflectiveMessageValidator;
+import org.eclipse.lsp4j.services.LanguageClient;
+import org.eclipse.lsp4j.services.LanguageServer;
+
+/**
+ * Specialized launcher for the Language Server Protocol.
+ */
+public final class LSPLauncher {
+	
+	private LSPLauncher() {}
+	
+	/**
+	 * Create a new Launcher for a language server and an input and output stream.
+	 * 
+	 * @param server - the server that receives method calls from the remote client
+	 * @param in - input stream to listen for incoming messages
+	 * @param out - output stream to send outgoing messages
+	 */
+	public static Launcher<LanguageClient> createServerLauncher(LanguageServer server, InputStream in, OutputStream out) {
+		return new Builder<LanguageClient>()
+				.setLocalService(server)
+				.setRemoteInterface(LanguageClient.class)
+				.setInput(in)
+				.setOutput(out)
+				.create();
+	}
+	
+	/**
+	 * Create a new Launcher for a language server and an input and output stream, and set up message validation and tracing.
+	 * 
+	 * @param server - the server that receives method calls from the remote client
+	 * @param in - input stream to listen for incoming messages
+	 * @param out - output stream to send outgoing messages
+	 * @param validate - whether messages should be validated with the {@link ReflectiveMessageValidator}
+	 * @param trace - a writer to which incoming and outgoing messages are traced, or {@code null} to disable tracing
+	 */
+	public static Launcher<LanguageClient> createServerLauncher(LanguageServer server, InputStream in, OutputStream out,
+			boolean validate, PrintWriter trace) {
+		return new Builder<LanguageClient>()
+				.setLocalService(server)
+				.setRemoteInterface(LanguageClient.class)
+				.setInput(in)
+				.setOutput(out)
+				.validateMessages(validate)
+				.traceMessages(trace)
+				.create();
+	}
+	
+	/**
+	 * Create a new Launcher for a language server and an input and output stream. Threads are started with the given
+	 * executor service. The wrapper function is applied to the incoming and outgoing message streams so additional
+	 * message handling such as validation and tracing can be included.
+	 * 
+	 * @param server - the server that receives method calls from the remote client
+	 * @param in - input stream to listen for incoming messages
+	 * @param out - output stream to send outgoing messages
+	 * @param executorService - the executor service used to start threads
+	 * @param wrapper - a function for plugging in additional message consumers
+	 */
+	public static Launcher<LanguageClient> createServerLauncher(LanguageServer server, InputStream in, OutputStream out,
+			ExecutorService executorService, Function<MessageConsumer, MessageConsumer> wrapper) {
+		return new Builder<LanguageClient>()
+				.setLocalService(server)
+				.setRemoteInterface(LanguageClient.class)
+				.setInput(in)
+				.setOutput(out)
+				.setExecutorService(executorService)
+				.wrapMessages(wrapper)
+				.create();
+	}
+	
+	/**
+	 * Create a new Launcher for a language client and an input and output stream.
+	 * 
+	 * @param client - the client that receives method calls from the remote server
+	 * @param in - input stream to listen for incoming messages
+	 * @param out - output stream to send outgoing messages
+	 */
+	public static Launcher<LanguageServer> createClientLauncher(LanguageClient client, InputStream in, OutputStream out) {
+		return new Builder<LanguageServer>()
+				.setLocalService(client)
+				.setRemoteInterface(LanguageServer.class)
+				.setInput(in)
+				.setOutput(out)
+				.create();
+	}
+	
+	/**
+	 * Create a new Launcher for a language client and an input and output stream, and set up message validation and tracing.
+	 * 
+	 * @param client - the client that receives method calls from the remote server
+	 * @param in - input stream to listen for incoming messages
+	 * @param out - output stream to send outgoing messages
+	 * @param validate - whether messages should be validated with the {@link ReflectiveMessageValidator}
+	 * @param trace - a writer to which incoming and outgoing messages are traced, or {@code null} to disable tracing
+	 */
+	public static Launcher<LanguageServer> createClientLauncher(LanguageClient client, InputStream in, OutputStream out,
+			boolean validate, PrintWriter trace) {
+		return new Builder<LanguageServer>()
+				.setLocalService(client)
+				.setRemoteInterface(LanguageServer.class)
+				.setInput(in)
+				.setOutput(out)
+				.validateMessages(validate)
+				.traceMessages(trace)
+				.create();
+	}
+	
+	/**
+	 * Create a new Launcher for a language client and an input and output stream. Threads are started with the given
+	 * executor service. The wrapper function is applied to the incoming and outgoing message streams so additional
+	 * message handling such as validation and tracing can be included.
+	 * 
+	 * @param client - the client that receives method calls from the remote server
+	 * @param in - input stream to listen for incoming messages
+	 * @param out - output stream to send outgoing messages
+	 * @param executorService - the executor service used to start threads
+	 * @param wrapper - a function for plugging in additional message consumers
+	 */
+	public static Launcher<LanguageServer> createClientLauncher(LanguageClient client, InputStream in, OutputStream out,
+			ExecutorService executorService, Function<MessageConsumer, MessageConsumer> wrapper) {
+		return new Builder<LanguageServer>()
+				.setLocalService(client)
+				.setRemoteInterface(LanguageServer.class)
+				.setInput(in)
+				.setOutput(out)
+				.setExecutorService(executorService)
+				.wrapMessages(wrapper)
+				.create();
+	}
+	
+	/**
+	 * Launcher builder for the Language Server Protocol.
+	 */
+	public static class Builder<T> extends Launcher.Builder<T> {
+		
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/services/LanguageClient.java b/java/org/eclipse/lsp4j/services/LanguageClient.java
new file mode 100644
index 0000000..2d0d5d7
--- /dev/null
+++ b/java/org/eclipse/lsp4j/services/LanguageClient.java
@@ -0,0 +1,210 @@
+/******************************************************************************
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.services;
+
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+import org.eclipse.lsp4j.ApplyWorkspaceEditParams;
+import org.eclipse.lsp4j.ApplyWorkspaceEditResponse;
+import org.eclipse.lsp4j.ConfigurationParams;
+import org.eclipse.lsp4j.LogTraceParams;
+import org.eclipse.lsp4j.MessageActionItem;
+import org.eclipse.lsp4j.MessageParams;
+import org.eclipse.lsp4j.ProgressParams;
+import org.eclipse.lsp4j.PublishDiagnosticsParams;
+import org.eclipse.lsp4j.RegistrationParams;
+import org.eclipse.lsp4j.ShowDocumentParams;
+import org.eclipse.lsp4j.ShowDocumentResult;
+import org.eclipse.lsp4j.ShowMessageRequestParams;
+import org.eclipse.lsp4j.UnregistrationParams;
+import org.eclipse.lsp4j.WorkDoneProgressCreateParams;
+import org.eclipse.lsp4j.WorkspaceFolder;
+import org.eclipse.lsp4j.jsonrpc.services.JsonNotification;
+import org.eclipse.lsp4j.jsonrpc.services.JsonRequest;
+
+public interface LanguageClient {
+	/**
+	 * The workspace/applyEdit request is sent from the server to the client to modify resource on the client side.
+	 */
+	@JsonRequest("workspace/applyEdit")
+	default CompletableFuture<ApplyWorkspaceEditResponse> applyEdit(ApplyWorkspaceEditParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The client/registerCapability request is sent from the server to the client
+	 * to register for a new capability on the client side.
+	 * Not all clients need to support dynamic capability registration.
+	 * A client opts in via the ClientCapabilities.dynamicRegistration property
+	 */
+	@JsonRequest("client/registerCapability")
+	default CompletableFuture<Void> registerCapability(RegistrationParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The client/unregisterCapability request is sent from the server to the client
+	 * to unregister a previously register capability.
+	 */
+	@JsonRequest("client/unregisterCapability")
+	default CompletableFuture<Void> unregisterCapability(UnregistrationParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The telemetry notification is sent from the server to the client to ask
+	 * the client to log a telemetry event.
+	 */
+	@JsonNotification("telemetry/event")
+	void telemetryEvent(Object object);
+
+	/**
+	 * Diagnostics notifications are sent from the server to the client to
+	 * signal results of validation runs.
+	 */
+	@JsonNotification("textDocument/publishDiagnostics")
+	void publishDiagnostics(PublishDiagnosticsParams diagnostics);
+
+	/**
+	 * The show message notification is sent from a server to a client to ask
+	 * the client to display a particular message in the user interface.
+	 */
+	@JsonNotification("window/showMessage")
+	void showMessage(MessageParams messageParams);
+
+	/**
+	 * The show message request is sent from a server to a client to ask the
+	 * client to display a particular message in the user interface. In addition
+	 * to the show message notification the request allows to pass actions and
+	 * to wait for an answer from the client.
+	 */
+	@JsonRequest("window/showMessageRequest")
+	CompletableFuture<MessageActionItem> showMessageRequest(ShowMessageRequestParams requestParams);
+
+	/**
+	 * The show document request is sent from a server to a client to ask the
+	 * client to display a particular document in the user interface.
+	 * 
+	 * Since 3.16.0
+	 */
+	@JsonRequest("window/showDocument")
+	default CompletableFuture<ShowDocumentResult> showDocument(ShowDocumentParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The log message notification is send from the server to the client to ask
+	 * the client to log a particular message.
+	 */
+	@JsonNotification("window/logMessage")
+	void logMessage(MessageParams message);
+
+	/**
+	 * The workspace/workspaceFolders request is sent from the server to the client
+	 * to fetch the current open list of workspace folders.
+	 *
+	 * @return null in the response if only a single file is open in the tool,
+	 *         an empty array if a workspace is open but no folders are configured,
+	 *         the workspace folders otherwise.
+	 * 
+	 * Since 3.6.0
+	 */
+	@JsonRequest("workspace/workspaceFolders")
+	default CompletableFuture<List<WorkspaceFolder>> workspaceFolders() {
+		throw new UnsupportedOperationException();
+	}
+	
+	/**
+	 * The workspace/configuration request is sent from the server to the client to fetch
+	 * configuration settings from the client. The request can fetch several configuration settings
+	 * in one roundtrip. The order of the returned configuration settings correspond to the
+	 * order of the passed ConfigurationItems (e.g. the first item in the response is the
+	 * result for the first configuration item in the params).
+	 * 
+	 * Since 3.6.0
+	 */
+	@JsonRequest("workspace/configuration")
+	default CompletableFuture<List<Object>> configuration(ConfigurationParams configurationParams) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * This request is sent from the server to the client to ask the client to create a work done progress.
+	 * 
+	 * Since 3.15.0
+	 */
+	@JsonRequest("window/workDoneProgress/create")
+	default CompletableFuture<Void> createProgress(WorkDoneProgressCreateParams params) {
+		throw new UnsupportedOperationException();
+	}
+	
+	/**
+	 * The base protocol offers also support to report progress in a generic fashion.
+	 * This mechanism can be used to report any kind of progress including work done progress
+	 * (usually used to report progress in the user interface using a progress bar)
+	 * and partial result progress to support streaming of results.
+	 * 
+	 * Since 3.15.0
+	 */
+	@JsonNotification("$/progress")
+	default void notifyProgress(ProgressParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * A notification to log the trace of the server's execution. The amount and content of these
+	 * notifications depends on the current trace configuration. If trace is 'off', the server
+	 * should not send any logTrace notification. If trace is 'message', the server should not
+	 * add the 'verbose' field in the LogTraceParams.
+	 *
+	 * $/logTrace should be used for systematic trace reporting. For single debugging messages,
+	 * the server should send window/logMessage notifications.
+	 * 
+	 * Since 3.16.0
+	 */
+	@JsonNotification("$/logTrace")
+	default void logTrace(LogTraceParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The `workspace/semanticTokens/refresh` request is sent from the server to the client.
+	 * Servers can use it to ask clients to refresh the editors for which this server
+	 * provides semantic tokens. As a result the client should ask the server to recompute
+	 * the semantic tokens for these editors. This is useful if a server detects a project wide
+	 * configuration change which requires a re-calculation of all semantic tokens.
+	 * Note that the client still has the freedom to delay the re-calculation of the semantic tokens
+	 * if for example an editor is currently not visible.
+	 * 
+	 * Since 3.16.0
+	 */
+	@JsonRequest("workspace/semanticTokens/refresh")
+	default CompletableFuture<Void> refreshSemanticTokens() {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The {@code workspace/codeLens/refresh} request is sent from the server to the client.
+	 * Servers can use it to ask clients to refresh the code lenses currently shown in editors.
+	 * As a result the client should ask the server to recompute the code lenses for these editors.
+	 * This is useful if a server detects a configuration change which requires a re-calculation of
+	 * all code lenses. Note that the client still has the freedom to delay the re-calculation of
+	 * the code lenses if for example an editor is currently not visible.
+	 * 
+	 * Since 3.16.0
+	 */
+	@JsonRequest("workspace/codeLens/refresh")
+	default CompletableFuture<Void> refreshCodeLenses() {
+		throw new UnsupportedOperationException();
+	}
+}
diff --git a/java/org/eclipse/lsp4j/services/LanguageClientAware.java b/java/org/eclipse/lsp4j/services/LanguageClientAware.java
new file mode 100644
index 0000000..64d709b
--- /dev/null
+++ b/java/org/eclipse/lsp4j/services/LanguageClientAware.java
@@ -0,0 +1,17 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.services;
+
+public interface LanguageClientAware {
+
+	void connect(LanguageClient client);
+}
diff --git a/java/org/eclipse/lsp4j/services/LanguageClientExtensions.java b/java/org/eclipse/lsp4j/services/LanguageClientExtensions.java
new file mode 100644
index 0000000..de2f1f7
--- /dev/null
+++ b/java/org/eclipse/lsp4j/services/LanguageClientExtensions.java
@@ -0,0 +1,20 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.services;
+
+
+/**
+ * An extension interface for new methods that are not (yet) defined in the standard LSP protocol.
+ */
+public interface LanguageClientExtensions extends LanguageClient {
+
+}
diff --git a/java/org/eclipse/lsp4j/services/LanguageServer.java b/java/org/eclipse/lsp4j/services/LanguageServer.java
new file mode 100644
index 0000000..ec4e4e7
--- /dev/null
+++ b/java/org/eclipse/lsp4j/services/LanguageServer.java
@@ -0,0 +1,112 @@
+/******************************************************************************
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.services;
+
+import java.util.concurrent.CompletableFuture;
+
+import org.eclipse.lsp4j.InitializeParams;
+import org.eclipse.lsp4j.InitializeResult;
+import org.eclipse.lsp4j.InitializedParams;
+import org.eclipse.lsp4j.SetTraceParams;
+import org.eclipse.lsp4j.WorkDoneProgressCancelParams;
+import org.eclipse.lsp4j.jsonrpc.services.JsonDelegate;
+import org.eclipse.lsp4j.jsonrpc.services.JsonNotification;
+import org.eclipse.lsp4j.jsonrpc.services.JsonRequest;
+
+/**
+ * Interface for implementations of
+ * https://github.com/Microsoft/vscode-languageserver-protocol
+ */
+public interface LanguageServer {
+	/**
+	 * The initialize request is sent as the first request from the client to
+	 * the server.
+	 * 
+	 * If the server receives requests or notifications before the initialize request, it should act as follows:
+	 *  - for a request, the response should be errored with:
+	 *    {@link org.eclipse.lsp4j.jsonrpc.messages.ResponseErrorCode#serverNotInitialized}.
+	 *    The message can be picked by the server.
+	 *  - notifications should be dropped, except for the exit notification.
+	 *    This will allow the client to exit a server without an initialize request.
+	 *  
+	 * Until the server has responded to the initialize request with an InitializeResult,
+	 * the client must not send any additional requests or notifications to the server.
+	 * 
+	 * During the initialize request, the server is allowed to send the notifications window/showMessage,
+	 * window/logMessage, and telemetry/event, as well as the request window/showMessageRequest, to the client.
+	 */
+	@JsonRequest
+	CompletableFuture<InitializeResult> initialize(InitializeParams params);
+
+	/**
+	 * The initialized notification is sent from the client to the server after
+	 * the client received the result of the initialize request, but before the
+	 * client is sending any other request or notification to the server. The
+	 * server can use the initialized notification, for example, to dynamically
+	 * register capabilities.
+	 */
+	@JsonNotification
+	default void initialized(InitializedParams params) {
+		initialized();
+	}
+	/**
+	 * @deprecated see initialized(InitializedParams)
+	 */
+	@Deprecated
+	default void initialized() {
+	}
+
+	/**
+	 * The shutdown request is sent from the client to the server. It asks the
+	 * server to shutdown, but to not exit (otherwise the response might not be
+	 * delivered correctly to the client). There is a separate exit notification
+	 * that asks the server to exit.
+	 */
+	@JsonRequest
+	CompletableFuture<Object> shutdown();
+
+	/**
+	 * A notification to ask the server to exit its process.
+	 */
+	@JsonNotification
+	void exit();
+
+	/**
+	 * Provides access to the textDocument services.
+	 */
+	@JsonDelegate
+	TextDocumentService getTextDocumentService();
+
+	/**
+	 * Provides access to the workspace services.
+	 */
+	@JsonDelegate
+	WorkspaceService getWorkspaceService();
+	
+	/**
+	 * This notification is sent from the client to the server to cancel a progress initiated on the server side.
+	 */
+	@JsonNotification("window/workDoneProgress/cancel")
+	default void cancelProgress(WorkDoneProgressCancelParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * A notification that should be used by the client to modify the trace setting of the server.
+	 *
+	 * Since 3.16.0
+	 */
+	@JsonNotification("$/setTrace")
+	default void setTrace(SetTraceParams params) {
+		throw new UnsupportedOperationException();
+	}
+}
diff --git a/java/org/eclipse/lsp4j/services/TextDocumentService.java b/java/org/eclipse/lsp4j/services/TextDocumentService.java
new file mode 100644
index 0000000..9c4a9aa
--- /dev/null
+++ b/java/org/eclipse/lsp4j/services/TextDocumentService.java
@@ -0,0 +1,628 @@
+/******************************************************************************
+ * Copyright (c) 2016-2018 TypeFox and others.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.services;
+
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+import com.google.common.annotations.Beta;
+
+import org.eclipse.lsp4j.CallHierarchyIncomingCall;
+import org.eclipse.lsp4j.CallHierarchyIncomingCallsParams;
+import org.eclipse.lsp4j.CallHierarchyItem;
+import org.eclipse.lsp4j.CallHierarchyOutgoingCall;
+import org.eclipse.lsp4j.CallHierarchyOutgoingCallsParams;
+import org.eclipse.lsp4j.CallHierarchyPrepareParams;
+import org.eclipse.lsp4j.CodeAction;
+import org.eclipse.lsp4j.CodeActionParams;
+import org.eclipse.lsp4j.CodeLens;
+import org.eclipse.lsp4j.CodeLensParams;
+import org.eclipse.lsp4j.ColorInformation;
+import org.eclipse.lsp4j.ColorPresentation;
+import org.eclipse.lsp4j.ColorPresentationParams;
+import org.eclipse.lsp4j.Command;
+import org.eclipse.lsp4j.CompletionItem;
+import org.eclipse.lsp4j.CompletionList;
+import org.eclipse.lsp4j.CompletionParams;
+import org.eclipse.lsp4j.DeclarationParams;
+import org.eclipse.lsp4j.DefinitionParams;
+import org.eclipse.lsp4j.DidChangeTextDocumentParams;
+import org.eclipse.lsp4j.DidCloseTextDocumentParams;
+import org.eclipse.lsp4j.DidOpenTextDocumentParams;
+import org.eclipse.lsp4j.DidSaveTextDocumentParams;
+import org.eclipse.lsp4j.DocumentColorParams;
+import org.eclipse.lsp4j.DocumentFormattingParams;
+import org.eclipse.lsp4j.DocumentHighlight;
+import org.eclipse.lsp4j.DocumentHighlightParams;
+import org.eclipse.lsp4j.DocumentLink;
+import org.eclipse.lsp4j.DocumentLinkParams;
+import org.eclipse.lsp4j.DocumentOnTypeFormattingParams;
+import org.eclipse.lsp4j.DocumentRangeFormattingParams;
+import org.eclipse.lsp4j.DocumentSymbol;
+import org.eclipse.lsp4j.DocumentSymbolCapabilities;
+import org.eclipse.lsp4j.DocumentSymbolParams;
+import org.eclipse.lsp4j.FoldingRange;
+import org.eclipse.lsp4j.FoldingRangeRequestParams;
+import org.eclipse.lsp4j.Hover;
+import org.eclipse.lsp4j.HoverParams;
+import org.eclipse.lsp4j.ImplementationParams;
+import org.eclipse.lsp4j.Location;
+import org.eclipse.lsp4j.Moniker;
+import org.eclipse.lsp4j.MonikerParams;
+import org.eclipse.lsp4j.LocationLink;
+import org.eclipse.lsp4j.LinkedEditingRangeParams;
+import org.eclipse.lsp4j.LinkedEditingRanges;
+import org.eclipse.lsp4j.PrepareRenameParams;
+import org.eclipse.lsp4j.PrepareRenameResult;
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.ReferenceParams;
+import org.eclipse.lsp4j.RenameParams;
+import org.eclipse.lsp4j.ResolveTypeHierarchyItemParams;
+import org.eclipse.lsp4j.SelectionRange;
+import org.eclipse.lsp4j.SelectionRangeParams;
+import org.eclipse.lsp4j.SemanticTokens;
+import org.eclipse.lsp4j.SemanticTokensDelta;
+import org.eclipse.lsp4j.SemanticTokensDeltaParams;
+import org.eclipse.lsp4j.SemanticTokensParams;
+import org.eclipse.lsp4j.SemanticTokensRangeParams;
+import org.eclipse.lsp4j.SignatureHelp;
+import org.eclipse.lsp4j.SignatureHelpParams;
+import org.eclipse.lsp4j.SymbolInformation;
+import org.eclipse.lsp4j.TextDocumentRegistrationOptions;
+import org.eclipse.lsp4j.TextEdit;
+import org.eclipse.lsp4j.TypeDefinitionParams;
+import org.eclipse.lsp4j.TypeHierarchyItem;
+import org.eclipse.lsp4j.TypeHierarchyParams;
+import org.eclipse.lsp4j.WillSaveTextDocumentParams;
+import org.eclipse.lsp4j.WorkspaceEdit;
+import org.eclipse.lsp4j.adapters.CodeActionResponseAdapter;
+import org.eclipse.lsp4j.adapters.DocumentSymbolResponseAdapter;
+import org.eclipse.lsp4j.adapters.LocationLinkListAdapter;
+import org.eclipse.lsp4j.adapters.PrepareRenameResponseAdapter;
+import org.eclipse.lsp4j.adapters.SemanticTokensFullDeltaResponseAdapter;
+import org.eclipse.lsp4j.jsonrpc.json.ResponseJsonAdapter;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.services.JsonNotification;
+import org.eclipse.lsp4j.jsonrpc.services.JsonRequest;
+import org.eclipse.lsp4j.jsonrpc.services.JsonSegment;
+
+@JsonSegment("textDocument")
+public interface TextDocumentService {
+
+	/**
+	 * The Completion request is sent from the client to the server to compute
+	 * completion items at a given cursor position. Completion items are
+	 * presented in the IntelliSense user interface. If computing complete
+	 * completion items is expensive servers can additional provide a handler
+	 * for the resolve completion item request. This request is sent when a
+	 * completion item is selected in the user interface.
+	 * 
+	 * Registration Options: CompletionRegistrationOptions
+	 */
+	@JsonRequest
+	default CompletableFuture<Either<List<CompletionItem>, CompletionList>> completion(CompletionParams position) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The request is sent from the client to the server to resolve additional
+	 * information for a given completion item.
+	 */
+	@JsonRequest(value="completionItem/resolve", useSegment = false)
+	default CompletableFuture<CompletionItem> resolveCompletionItem(CompletionItem unresolved) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The hover request is sent from the client to the server to request hover
+	 * information at a given text document position.
+	 * 
+	 * Registration Options: TextDocumentRegistrationOptions
+	 */
+	@JsonRequest
+	default CompletableFuture<Hover> hover(HoverParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The signature help request is sent from the client to the server to
+	 * request signature information at a given cursor position.
+	 * 
+	 * Registration Options: SignatureHelpRegistrationOptions
+	 */
+	@JsonRequest
+	default CompletableFuture<SignatureHelp> signatureHelp(SignatureHelpParams params) {
+		throw new UnsupportedOperationException();
+	}
+	
+	/**
+	 * The go to declaration request is sent from the client to the server to resolve
+	 * the declaration location of a symbol at a given text document position.
+	 * 
+	 * Registration Options: TextDocumentRegistrationOptions
+	 * 
+	 * Since 3.14.0
+	 */
+	@JsonRequest
+	@ResponseJsonAdapter(LocationLinkListAdapter.class)
+	default CompletableFuture<Either<List<? extends Location>, List<? extends LocationLink>>> declaration(DeclarationParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The goto definition request is sent from the client to the server to resolve
+	 * the definition location of a symbol at a given text document position.
+	 * 
+	 * Registration Options: TextDocumentRegistrationOptions
+	 */
+	@JsonRequest
+	@ResponseJsonAdapter(LocationLinkListAdapter.class)
+	default CompletableFuture<Either<List<? extends Location>, List<? extends LocationLink>>> definition(DefinitionParams params) {
+		throw new UnsupportedOperationException();
+	}
+	
+	/**
+	 * The goto type definition request is sent from the client to the server to resolve
+	 * the type definition location of a symbol at a given text document position.
+	 * 
+	 * Registration Options: TextDocumentRegistrationOptions
+	 * 
+	 * Since 3.6.0
+	 */
+	@JsonRequest
+	@ResponseJsonAdapter(LocationLinkListAdapter.class)
+	default CompletableFuture<Either<List<? extends Location>, List<? extends LocationLink>>> typeDefinition(TypeDefinitionParams params) {
+		throw new UnsupportedOperationException();
+	}
+	
+	/**
+	 * The goto implementation request is sent from the client to the server to resolve
+	 * the implementation location of a symbol at a given text document position.
+	 * 
+	 * Registration Options: TextDocumentRegistrationOptions
+	 * 
+	 * Since 3.6.0
+	 */
+	@JsonRequest
+	@ResponseJsonAdapter(LocationLinkListAdapter.class)
+	default CompletableFuture<Either<List<? extends Location>, List<? extends LocationLink>>> implementation(ImplementationParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The references request is sent from the client to the server to resolve
+	 * project-wide references for the symbol denoted by the given text document
+	 * position.
+	 * 
+	 * Registration Options: TextDocumentRegistrationOptions
+	 */
+	@JsonRequest
+	default CompletableFuture<List<? extends Location>> references(ReferenceParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The document highlight request is sent from the client to the server to
+	 * to resolve a document highlights for a given text document position.
+	 * 
+	 * Registration Options: TextDocumentRegistrationOptions
+	 */
+	@JsonRequest
+	default CompletableFuture<List<? extends DocumentHighlight>> documentHighlight(DocumentHighlightParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The document symbol request is sent from the client to the server to list all
+	 * symbols found in a given text document.
+	 * 
+	 * Registration Options: {@link TextDocumentRegistrationOptions}
+	 * 
+	 * <p>
+	 * <b>Caveat</b>: although the return type allows mixing the
+	 * {@link DocumentSymbol} and {@link SymbolInformation} instances into a list do
+	 * not do it because the clients cannot accept a heterogeneous list. A list of
+	 * {@code DocumentSymbol} instances is only a valid return value if the
+	 * {@link DocumentSymbolCapabilities#getHierarchicalDocumentSymbolSupport()
+	 * textDocument.documentSymbol.hierarchicalDocumentSymbolSupport} is
+	 * {@code true}. More details on this difference between the LSP and the LSP4J
+	 * can be found <a href="https://github.com/eclipse/lsp4j/issues/252">here</a>.
+	 * </p>
+	 * 
+	 * Servers should whenever possible return {@code DocumentSymbol} since it is the richer data structure.
+	 */
+	@JsonRequest
+	@ResponseJsonAdapter(DocumentSymbolResponseAdapter.class)
+	default CompletableFuture<List<Either<SymbolInformation, DocumentSymbol>>> documentSymbol(DocumentSymbolParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The code action request is sent from the client to the server to compute
+	 * commands for a given text document and range. These commands are
+	 * typically code fixes to either fix problems or to beautify/refactor code.
+	 * 
+	 * Registration Options: TextDocumentRegistrationOptions
+	 */
+	@JsonRequest
+	@ResponseJsonAdapter(CodeActionResponseAdapter.class)
+	default CompletableFuture<List<Either<Command, CodeAction>>> codeAction(CodeActionParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The request is sent from the client to the server to resolve additional information for a given code action. This is usually used to compute
+	 * the `edit` property of a code action to avoid its unnecessary computation during the `textDocument/codeAction` request.
+	 * 
+	 * Since 3.16.0
+	 */
+	@JsonRequest(value="codeAction/resolve", useSegment = false)
+	default CompletableFuture<CodeAction> resolveCodeAction(CodeAction unresolved) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The code lens request is sent from the client to the server to compute
+	 * code lenses for a given text document.
+	 * 
+	 * Registration Options: CodeLensRegistrationOptions
+	 */
+	@JsonRequest
+	default CompletableFuture<List<? extends CodeLens>> codeLens(CodeLensParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The code lens resolve request is sent from the client to the server to
+	 * resolve the command for a given code lens item.
+	 */
+	@JsonRequest(value="codeLens/resolve", useSegment = false)
+	default CompletableFuture<CodeLens> resolveCodeLens(CodeLens unresolved) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The document formatting request is sent from the client to the server to
+	 * format a whole document.
+	 * 
+	 * Registration Options: TextDocumentRegistrationOptions
+	 */
+	@JsonRequest
+	default CompletableFuture<List<? extends TextEdit>> formatting(DocumentFormattingParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The document range formatting request is sent from the client to the
+	 * server to format a given range in a document.
+	 * 
+	 * Registration Options: TextDocumentRegistrationOptions
+	 */
+	@JsonRequest
+	default CompletableFuture<List<? extends TextEdit>> rangeFormatting(DocumentRangeFormattingParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The document on type formatting request is sent from the client to the
+	 * server to format parts of the document during typing.
+	 * 
+	 * Registration Options: DocumentOnTypeFormattingRegistrationOptions
+	 */
+	@JsonRequest
+	default CompletableFuture<List<? extends TextEdit>> onTypeFormatting(DocumentOnTypeFormattingParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The rename request is sent from the client to the server to do a
+	 * workspace wide rename of a symbol.
+	 * 
+	 * Registration Options: TextDocumentRegistrationOptions
+	 */
+	@JsonRequest
+	default CompletableFuture<WorkspaceEdit> rename(RenameParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The linked editing range request is sent from the client to the server to return
+	 * for a given position in a document the range of the symbol at the position
+	 * and all ranges that have the same content. Optionally a word pattern can be
+	 * returned to describe valid contents. A rename to one of the ranges can be
+	 * applied to all other ranges if the new content is valid. If no result-specific
+	 * word pattern is provided, the word pattern from the client's language configuration
+	 * is used.
+	 * 
+	 * Registration Options: LinkedEditingRangeRegistrationOptions
+	 * 
+	 * Since 3.16.0
+	 */
+	@JsonRequest
+	default CompletableFuture<LinkedEditingRanges> linkedEditingRange(LinkedEditingRangeParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The document open notification is sent from the client to the server to
+	 * signal newly opened text documents. The document's truth is now managed
+	 * by the client and the server must not try to read the document's truth
+	 * using the document's uri.
+	 * 
+	 * Registration Options: TextDocumentRegistrationOptions
+	 */
+	@JsonNotification
+	void didOpen(DidOpenTextDocumentParams params);
+
+	/**
+	 * The document change notification is sent from the client to the server to
+	 * signal changes to a text document.
+	 * 
+	 * Registration Options: TextDocumentChangeRegistrationOptions
+	 */
+	@JsonNotification
+	void didChange(DidChangeTextDocumentParams params);
+
+	/**
+	 * The document close notification is sent from the client to the server
+	 * when the document got closed in the client. The document's truth now
+	 * exists where the document's uri points to (e.g. if the document's uri is
+	 * a file uri the truth now exists on disk).
+	 * 
+	 * Registration Options: TextDocumentRegistrationOptions
+	 */
+	@JsonNotification
+	void didClose(DidCloseTextDocumentParams params);
+
+	/**
+	 * The document save notification is sent from the client to the server when
+	 * the document for saved in the client.
+	 * 
+	 * Registration Options: TextDocumentSaveRegistrationOptions
+	 */
+	@JsonNotification
+	void didSave(DidSaveTextDocumentParams params);
+
+	/**
+	 * The document will save notification is sent from the client to the server before the document is actually saved.
+	 * 
+	 * Registration Options: TextDocumentRegistrationOptions
+	 */
+	@JsonNotification
+	default void willSave(WillSaveTextDocumentParams params) {}
+	
+	/**
+	 * The document will save request is sent from the client to the server before the document is actually saved.
+	 * The request can return an array of TextEdits which will be applied to the text document before it is saved.
+	 * Please note that clients might drop results if computing the text edits took too long or if a server constantly fails on this request.
+	 * This is done to keep the save fast and reliable.
+	 * 
+	 * Registration Options: TextDocumentRegistrationOptions
+	 */
+	@JsonRequest
+	default CompletableFuture<List<TextEdit>> willSaveWaitUntil(WillSaveTextDocumentParams params) {
+		throw new UnsupportedOperationException();
+	}
+	
+	/**
+	 * The document links request is sent from the client to the server to request the location of links in a document.
+	 * 
+	 * Registration Options: DocumentLinkRegistrationOptions
+	 */
+	@JsonRequest
+	default CompletableFuture<List<DocumentLink>> documentLink(DocumentLinkParams params) {
+		throw new UnsupportedOperationException();
+	}
+	
+	/**
+	 * The document link resolve request is sent from the client to the server to resolve the target of a given document link.
+	 */
+	@JsonRequest(value="documentLink/resolve", useSegment = false)
+	default CompletableFuture<DocumentLink> documentLinkResolve(DocumentLink params) {
+		throw new UnsupportedOperationException();
+	}
+	
+	/**
+	 * The document color request is sent from the client to the server to list all color references found in a given text
+	 * document. Along with the range, a color value in RGB is returned.
+	 * 
+	 * Clients can use the result to decorate color references in an editor. For example:
+	 *  - Color boxes showing the actual color next to the reference
+	 *  - Show a color picker when a color reference is edited
+	 * 
+	 * Since 3.6.0
+	 */
+	@JsonRequest
+	default CompletableFuture<List<ColorInformation>> documentColor(DocumentColorParams params) {
+		throw new UnsupportedOperationException();
+	}
+	
+	/**
+	 * The color presentation request is sent from the client to the server to obtain a list of presentations for a color
+	 * value at a given location. Clients can use the result to
+	 *  - modify a color reference.
+	 *  - show in a color picker and let users pick one of the presentations
+	 * 
+	 * Since 3.6.0
+	 */
+	@JsonRequest
+	default CompletableFuture<List<ColorPresentation>> colorPresentation(ColorPresentationParams params) {
+		throw new UnsupportedOperationException();
+	}
+	
+	/**
+	 * The folding range request is sent from the client to the server to return all folding
+	 * ranges found in a given text document.
+	 * 
+	 * Since 3.10.0
+	 */
+	@JsonRequest
+	default CompletableFuture<List<FoldingRange>> foldingRange(FoldingRangeRequestParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The prepare rename request is sent from the client to the server to setup and test the validity of a rename
+	 * operation at a given location.
+	 * 
+	 * Since 3.12.0
+	 */
+	@JsonRequest
+	@ResponseJsonAdapter(PrepareRenameResponseAdapter.class)
+	default CompletableFuture<Either<Range, PrepareRenameResult>> prepareRename(PrepareRenameParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The {@code textDocument/typeHierarchy} request is sent from the client to the
+	 * server to retrieve a {@link TypeHierarchyItem type hierarchy item} based on
+	 * the {@link TypeHierarchyParams cursor position in the text document}. This
+	 * request would also allow to specify if the item should be resolved and
+	 * whether sub- or supertypes are to be resolved. If no type hierarchy item can
+	 * be found under the given text document position, resolves to {@code null}.
+	 * 
+	 * <p>
+	 * <b>Note:</b> the <a href=
+	 * "https://github.com/Microsoft/vscode-languageserver-node/pull/426">{@code textDocument/typeHierarchy}
+	 * language feature</a> is not yet part of the official LSP specification.
+	 */
+	@Beta
+	@JsonRequest
+	default CompletableFuture<TypeHierarchyItem> typeHierarchy(TypeHierarchyParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The {@code typeHierarchy/resolve} request is sent from the client to the
+	 * server to resolve an unresolved {@link TypeHierarchyItem type hierarchy
+	 * item}. A type hierarchy item is unresolved if the if the
+	 * {@link TypeHierarchyItem#getParents parents} or the
+	 * {@link TypeHierarchyItem#getChildren children} is not defined.
+	 * 
+	 * <p>
+	 * <b>Note:</b> the <a href=
+	 * "https://github.com/Microsoft/vscode-languageserver-node/pull/426">{@code textDocument/typeHierarchy}
+	 * language feature</a> is not yet part of the official LSP specification.
+	 */
+	@Beta
+	@JsonRequest(value="typeHierarchy/resolve", useSegment = false)
+	default CompletableFuture<TypeHierarchyItem> resolveTypeHierarchy(ResolveTypeHierarchyItemParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Bootstraps call hierarchy by returning the item that is denoted by the given document
+	 * and position. This item will be used as entry into the call graph. Providers should
+	 * return null when there is no item at the given location.
+	 * 
+	 * Since 3.16.0
+	 */
+	@JsonRequest
+	default CompletableFuture<List<CallHierarchyItem>> prepareCallHierarchy(CallHierarchyPrepareParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Provide all incoming calls for an item, e.g all callers for a method. In graph terms this describes directed
+	 * and annotated edges inside the call graph, e.g the given item is the starting node and the result is the nodes
+	 * that can be reached.
+	 * 
+	 * Since 3.16.0
+	*/
+	@JsonRequest(value="callHierarchy/incomingCalls", useSegment = false)
+	default CompletableFuture<List<CallHierarchyIncomingCall>> callHierarchyIncomingCalls(CallHierarchyIncomingCallsParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	* Provide all outgoing calls for an item, e.g call calls to functions, methods, or constructors from the given item. In
+	* graph terms this describes directed and annotated edges inside the call graph, e.g the given item is the starting
+	* node and the result is the nodes that can be reached.
+	* 
+	* Since 3.16.0
+	*/
+	@JsonRequest(value="callHierarchy/outgoingCalls", useSegment = false)
+	default CompletableFuture<List<CallHierarchyOutgoingCall>> callHierarchyOutgoingCalls(CallHierarchyOutgoingCallsParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The {@code textDocument/selectionRange} request is sent from the client to the server to return
+	 * suggested selection ranges at an array of given positions. A selection range is a range around
+	 * the cursor position which the user might be interested in selecting.
+	 * 
+	 * Since 3.15.0
+	 */
+	@JsonRequest
+	default CompletableFuture<List<SelectionRange>> selectionRange(SelectionRangeParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The {@code textDocument/semanticTokens/full} request is sent from the client to the server to return
+	 * the semantic tokens for a whole file.
+	 * 
+	 * Since 3.16.0
+	 */
+	@JsonRequest(value="textDocument/semanticTokens/full", useSegment = false)
+	default CompletableFuture<SemanticTokens> semanticTokensFull(SemanticTokensParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The {@code textDocument/semanticTokens/full/delta} request is sent from the client to the server to return
+	 * the semantic tokens delta for a whole file.
+	 * 
+	 * Since 3.16.0
+	 */
+	@JsonRequest(value="textDocument/semanticTokens/full/delta", useSegment = false)
+	@ResponseJsonAdapter(SemanticTokensFullDeltaResponseAdapter.class)
+	default CompletableFuture<Either<SemanticTokens, SemanticTokensDelta>> semanticTokensFullDelta(SemanticTokensDeltaParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The {@code textDocument/semanticTokens/range} request is sent from the client to the server to return
+	 * the semantic tokens delta for a range.
+	 *
+	 * When a user opens a file it can be beneficial to only compute the semantic tokens for the visible range
+	 * (faster rendering of the tokens in the user interface). If a server can compute these tokens faster than
+	 * for the whole file it can provide a handler for the textDocument/semanticTokens/range request to handle
+	 * this case special. Please note that if a client also announces that it will send the
+	 * textDocument/semanticTokens/range server should implement this request as well to allow for flicker free
+	 * scrolling and semantic coloring of a minimap.
+	 * 
+	 * Since 3.16.0
+	 */
+	@JsonRequest(value="textDocument/semanticTokens/range", useSegment = false)
+	default CompletableFuture<SemanticTokens> semanticTokensRange(SemanticTokensRangeParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Language Server Index Format (LSIF) introduced the concept of symbol monikers to help associate symbols across
+	 * different indexes. This request adds capability for LSP server implementations to provide the same symbol moniker
+	 * information given a text document position. Clients can utilize this method to get the moniker at the current
+	 * location in a file user is editing and do further code navigation queries in other services that rely on LSIF indexes
+	 * and link symbols together.
+	 *
+	 * The {@code textDocument/moniker} request is sent from the client to the server to get the symbol monikers for a given
+	 * text document position. An array of Moniker types is returned as response to indicate possible monikers at the given location.
+	 * If no monikers can be calculated, an empty array or null should be returned.
+	 * 
+	 * Since 3.16.0
+	 */
+	@JsonRequest
+	default CompletableFuture<List<Moniker>> moniker(MonikerParams params) {
+		throw new UnsupportedOperationException();
+	}
+}
diff --git a/java/org/eclipse/lsp4j/services/WorkspaceService.java b/java/org/eclipse/lsp4j/services/WorkspaceService.java
new file mode 100644
index 0000000..1f585ce
--- /dev/null
+++ b/java/org/eclipse/lsp4j/services/WorkspaceService.java
@@ -0,0 +1,163 @@
+/******************************************************************************
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.services;
+
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+import org.eclipse.lsp4j.CreateFilesParams;
+import org.eclipse.lsp4j.DeleteFilesParams;
+import org.eclipse.lsp4j.DidChangeConfigurationParams;
+import org.eclipse.lsp4j.DidChangeWatchedFilesParams;
+import org.eclipse.lsp4j.DidChangeWorkspaceFoldersParams;
+import org.eclipse.lsp4j.ExecuteCommandParams;
+import org.eclipse.lsp4j.RenameFilesParams;
+import org.eclipse.lsp4j.SymbolInformation;
+import org.eclipse.lsp4j.WorkspaceEdit;
+import org.eclipse.lsp4j.WorkspaceSymbolParams;
+import org.eclipse.lsp4j.jsonrpc.services.JsonNotification;
+import org.eclipse.lsp4j.jsonrpc.services.JsonRequest;
+import org.eclipse.lsp4j.jsonrpc.services.JsonSegment;
+
+@JsonSegment("workspace")
+public interface WorkspaceService {
+	/**
+	 * The workspace/executeCommand request is sent from the client to the
+	 * server to trigger command execution on the server. In most cases the
+	 * server creates a WorkspaceEdit structure and applies the changes to the
+	 * workspace using the request workspace/applyEdit which is sent from the
+	 * server to the client.
+	 *
+	 * Registration Options: ExecuteCommandRegistrationOptions
+	 */
+	@JsonRequest
+	default CompletableFuture<Object> executeCommand(ExecuteCommandParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The workspace symbol request is sent from the client to the server to
+	 * list project-wide symbols matching the query string.
+	 *
+	 * Registration Options: void
+	 */
+	@JsonRequest
+	default CompletableFuture<List<? extends SymbolInformation>> symbol(WorkspaceSymbolParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * A notification sent from the client to the server to signal the change of
+	 * configuration settings.
+	 */
+	@JsonNotification
+	void didChangeConfiguration(DidChangeConfigurationParams params);
+
+	/**
+	 * The watched files notification is sent from the client to the server when
+	 * the client detects changes to file watched by the language client.
+	 */
+	@JsonNotification
+	void didChangeWatchedFiles(DidChangeWatchedFilesParams params);
+
+	/**
+	 * The workspace/didChangeWorkspaceFolders notification is sent from the client
+	 * to the server to inform the server about workspace folder configuration changes.
+	 * The notification is sent by default if both ServerCapabilities/workspaceFolders
+	 * and ClientCapabilities/workspace/workspaceFolders are true; or if the server has
+	 * registered to receive this notification it first.
+	 * 
+	 * Since 3.6.0
+	 */
+	@JsonNotification
+	default void didChangeWorkspaceFolders(DidChangeWorkspaceFoldersParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The will create files request is sent from the client to the server before files
+	 * are actually created as long as the creation is triggered from within the client.
+	 * The request can return a {@link WorkspaceEdit} which will be applied to workspace
+	 * before the files are created. Please note that clients might drop results if computing
+	 * the edit took too long or if a server constantly fails on this request. This is
+	 * done to keep creates fast and reliable.
+	 *
+	 * Since 3.16.0
+	 */
+	@JsonRequest
+	default CompletableFuture<WorkspaceEdit> willCreateFiles(CreateFilesParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The did create files notification is sent from the client to the server when files
+	 * were created from within the client.
+	 * 
+	 * Since 3.16.0
+	 */
+	@JsonNotification
+	default void didCreateFiles(CreateFilesParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The will rename files request is sent from the client to the server before files
+	 * are actually renamed as long as the rename is triggered from within the client.
+	 * The request can return a {@link WorkspaceEdit} which will be applied to workspace
+	 * before the files are renamed. Please note that clients might drop results if computing
+	 * the edit took too long or if a server constantly fails on this request. This is
+	 * done to keep renames fast and reliable.
+	 *
+	 * Since 3.16.0
+	 */
+	@JsonRequest
+	default CompletableFuture<WorkspaceEdit> willRenameFiles(RenameFilesParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The did rename files notification is sent from the client to the server when files
+	 * were renamed from within the client.
+	 * 
+	 * Since 3.16.0
+	 */
+	@JsonNotification
+	default void didRenameFiles(RenameFilesParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The will delete files request is sent from the client to the server before files
+	 * are actually deleted as long as the deletion is triggered from within the client.
+	 * The request can return a {@link WorkspaceEdit} which will be applied to workspace
+	 * before the files are deleted. Please note that clients might drop results if computing
+	 * the edit took too long or if a server constantly fails on this request. This is
+	 * done to keep deletes fast and reliable.
+	 *
+	 * Since 3.16.0
+	 */
+	@JsonRequest
+	default CompletableFuture<WorkspaceEdit> willDeleteFiles(DeleteFilesParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * The did delete files notification is sent from the client to the server when files
+	 * were deleted from within the client.
+	 * 
+	 * Since 3.16.0
+	 */
+	@JsonNotification
+	default void didDeleteFiles(DeleteFilesParams params) {
+		throw new UnsupportedOperationException();
+	}
+}
diff --git a/java/org/eclipse/lsp4j/util/DocumentSymbols.java b/java/org/eclipse/lsp4j/util/DocumentSymbols.java
new file mode 100644
index 0000000..0763b02
--- /dev/null
+++ b/java/org/eclipse/lsp4j/util/DocumentSymbols.java
@@ -0,0 +1,96 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.util;
+
+import java.util.ArrayDeque;
+import java.util.Iterator;
+import java.util.Queue;
+
+import org.eclipse.lsp4j.DocumentSymbol;
+
+/**
+ * Utilities for {@link DocumentSymbol document symbols}.
+ */
+public final class DocumentSymbols {
+
+	/**
+	 * Returns an unmodifiable iterator over the {@link DocumentSymbol document
+	 * symbols} using the breath-first traversal. That is, all the symbols of depth
+	 * 0 are returned, then depth 1, then 2, and so on.
+	 * 
+	 * <p>
+	 * It does not guarantee a well defined behavior of the resulting iterator if
+	 * you modify the structure while the iteration is in progress.
+	 */
+	public static Iterator<DocumentSymbol> asIterator(DocumentSymbol documentSymbol) {
+		return new DocumentSymbolIterator(documentSymbol);
+	}
+
+	protected static class DocumentSymbolIterator extends BreadthFirstIterator<DocumentSymbol> {
+
+		protected DocumentSymbolIterator(DocumentSymbol documentSymbol) {
+			super(Preconditions.checkNotNull(documentSymbol, "documentSymbol"));
+		}
+
+		@Override
+		protected Iterable<DocumentSymbol> getChildren(DocumentSymbol node) {
+			return node.getChildren();
+		}
+
+	}
+
+	protected abstract static class BreadthFirstIterator<T> implements Iterator<T> {
+
+		private Queue<T> queue;
+
+		protected BreadthFirstIterator(T root) {
+			Preconditions.checkNotNull(root, "root");
+			this.queue = new ArrayDeque<>();
+			this.queue.add(root);
+		}
+
+		@Override
+		public void remove() {
+			throw new UnsupportedOperationException();
+		}
+
+		@Override
+		public boolean hasNext() {
+			return !this.queue.isEmpty();
+		}
+
+		@Override
+		public T next() {
+			T result = queue.remove();
+			Iterable<T> children = getChildren(result);
+			if (children != null) {
+				for (T child : children) {
+					queue.add(child);
+				}
+			}
+			return result;
+		}
+
+		/**
+		 * Returns with the children (direct descendants) of the {@code node} argument.
+		 * If the argument does not have any children, clients are allowed to return
+		 * {@code null}.
+		 */
+		protected abstract Iterable<T> getChildren(T node);
+
+	}
+
+	private DocumentSymbols() {
+
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/util/Positions.java b/java/org/eclipse/lsp4j/util/Positions.java
new file mode 100644
index 0000000..a4affc7
--- /dev/null
+++ b/java/org/eclipse/lsp4j/util/Positions.java
@@ -0,0 +1,43 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.util;
+
+import org.eclipse.lsp4j.Position;
+
+/**
+ * Utilities for the {@link Position}.
+ */
+public final class Positions {
+
+	/**
+	 * {@code true} if {@code left} is strictly before than {@code right}. Otherwise,
+	 * {@code false}.
+	 * <p>
+	 * If you want to allow equality, use {@link Position#equals}.
+	 */
+	public static boolean isBefore(Position left, Position right) {
+		Preconditions.checkNotNull(left, "left");
+		Preconditions.checkNotNull(right, "right");
+		if (left.getLine() < right.getLine()) {
+			return true;
+		}
+		if (left.getLine() > right.getLine()) {
+			return false;
+		}
+		return left.getCharacter() < right.getCharacter();
+	}
+
+	private Positions() {
+
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/util/Preconditions.java b/java/org/eclipse/lsp4j/util/Preconditions.java
new file mode 100644
index 0000000..2319b7d
--- /dev/null
+++ b/java/org/eclipse/lsp4j/util/Preconditions.java
@@ -0,0 +1,34 @@
+/******************************************************************************
+ * Copyright (c) 2019 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.util;
+
+/**
+ * Utilities for checking method and constructor arguments.
+ */
+public final class Preconditions {
+	
+	private Preconditions() {}
+	
+	private static boolean nullChecks = true;
+	
+	public static void enableNullChecks(boolean enable) {
+		Preconditions.nullChecks = enable;
+	}
+	
+	public static <T> T checkNotNull(T object, String propertyName) {
+		if (nullChecks && object == null) {
+			throw new NullPointerException("Property must not be null: " + propertyName);
+		}
+		return object;
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/util/Ranges.java b/java/org/eclipse/lsp4j/util/Ranges.java
new file mode 100644
index 0000000..ebd4e69
--- /dev/null
+++ b/java/org/eclipse/lsp4j/util/Ranges.java
@@ -0,0 +1,47 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.util;
+
+import org.eclipse.lsp4j.Position;
+import org.eclipse.lsp4j.Range;
+
+/**
+ * Utility class for {@link Range}.
+ */
+public final class Ranges {
+
+	/**
+	 * {@code true} if the {@code smaller} {@link Range range} is inside or equal to
+	 * the {@code bigger} range. Otherwise, {@code false}.
+	 */
+	public static boolean containsRange(Range bigger, Range smaller) {
+		Preconditions.checkNotNull(bigger, "bigger");
+		Preconditions.checkNotNull(smaller, "smaller");
+		return containsPosition(bigger, smaller.getStart()) && containsPosition(bigger, smaller.getEnd());
+	}
+
+	/**
+	 * {@code true} if the {@link Position position} is either inside or on the
+	 * border of the {@link Range range}. Otherwise, {@code false}.
+	 */
+	public static boolean containsPosition(Range range, Position position) {
+		Preconditions.checkNotNull(range, "range");
+		Preconditions.checkNotNull(position, "position");
+		return (range.getStart().equals(position) || Positions.isBefore(range.getStart(), position)
+				&& (range.getEnd().equals(position) || Positions.isBefore(position, range.getEnd())));
+	}
+
+	private Ranges() {
+
+	}
+
+}
diff --git a/java/org/eclipse/lsp4j/websocket/WebSocketEndpoint.java b/java/org/eclipse/lsp4j/websocket/WebSocketEndpoint.java
new file mode 100644
index 0000000..efe675f
--- /dev/null
+++ b/java/org/eclipse/lsp4j/websocket/WebSocketEndpoint.java
@@ -0,0 +1,51 @@
+/******************************************************************************
+ * Copyright (c) 2019 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.websocket;
+
+import java.util.Collection;
+
+import javax.websocket.Endpoint;
+import javax.websocket.EndpointConfig;
+import javax.websocket.Session;
+
+import org.eclipse.lsp4j.jsonrpc.Launcher;
+
+/**
+ * WebSocket endpoint implementation that connects to a JSON-RPC service.
+ *
+ * @param <T> remote service interface type
+ */
+public abstract class WebSocketEndpoint<T> extends Endpoint {
+	
+	@Override
+	public void onOpen(Session session, EndpointConfig config) {
+		WebSocketLauncherBuilder<T> builder = new WebSocketLauncherBuilder<T>();
+		builder.setSession(session);
+		configure(builder);
+		Launcher<T> launcher = builder.create();
+		connect(builder.getLocalServices(), launcher.getRemoteProxy());
+	}
+	
+	/**
+	 * Configure the JSON-RPC launcher. Implementations should set at least the
+	 * {@link Launcher.Builder#setLocalService(Object) local service} and the
+	 * {@link Launcher.Builder#setRemoteInterface(Class) remote interface}.
+	 */
+	abstract protected void configure(Launcher.Builder<T> builder);
+	
+	/**
+	 * Override this in order to connect the local services to the remote service proxy.
+	 */
+	protected void connect(Collection<Object> localServices, T remoteProxy) {
+	}
+	
+}
diff --git a/java/org/eclipse/lsp4j/websocket/WebSocketLauncherBuilder.java b/java/org/eclipse/lsp4j/websocket/WebSocketLauncherBuilder.java
new file mode 100644
index 0000000..5a52886
--- /dev/null
+++ b/java/org/eclipse/lsp4j/websocket/WebSocketLauncherBuilder.java
@@ -0,0 +1,76 @@
+/******************************************************************************
+ * Copyright (c) 2019 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.websocket;
+
+import java.util.Collection;
+
+import javax.websocket.Session;
+
+import org.eclipse.lsp4j.jsonrpc.Endpoint;
+import org.eclipse.lsp4j.jsonrpc.Launcher;
+import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
+import org.eclipse.lsp4j.jsonrpc.RemoteEndpoint;
+import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
+import org.eclipse.lsp4j.jsonrpc.services.ServiceEndpoints;
+
+/**
+ * JSON-RPC launcher builder for use in {@link WebSocketEndpoint}.
+ *
+ * @param <T> remote service interface type
+ */
+public class WebSocketLauncherBuilder<T> extends Launcher.Builder<T> {
+	
+	protected Session session;
+	
+	public Collection<Object> getLocalServices() {
+		return localServices;
+	}
+	
+	public WebSocketLauncherBuilder<T> setSession(Session session) {
+		this.session = session;
+		return this;
+	}
+	
+	@Override
+	public Launcher<T> create() {
+		if (localServices == null)
+			throw new IllegalStateException("Local service must be configured.");
+		if (remoteInterfaces == null)
+			throw new IllegalStateException("Remote interface must be configured.");
+		
+		MessageJsonHandler jsonHandler = createJsonHandler();
+		RemoteEndpoint remoteEndpoint = createRemoteEndpoint(jsonHandler);
+		addMessageHandlers(jsonHandler, remoteEndpoint);
+		T remoteProxy = createProxy(remoteEndpoint);
+		return createLauncher(null, remoteProxy, remoteEndpoint, null);
+	}
+	
+	@Override
+	protected RemoteEndpoint createRemoteEndpoint(MessageJsonHandler jsonHandler) {
+		MessageConsumer outgoingMessageStream = new WebSocketMessageConsumer(session, jsonHandler);
+		outgoingMessageStream = wrapMessageConsumer(outgoingMessageStream);
+		Endpoint localEndpoint = ServiceEndpoints.toEndpoint(localServices);
+		RemoteEndpoint remoteEndpoint;
+		if (exceptionHandler == null)
+			remoteEndpoint = new RemoteEndpoint(outgoingMessageStream, localEndpoint);
+		else
+			remoteEndpoint = new RemoteEndpoint(outgoingMessageStream, localEndpoint, exceptionHandler);
+		jsonHandler.setMethodProvider(remoteEndpoint);
+		return remoteEndpoint;
+	}
+	
+	protected void addMessageHandlers(MessageJsonHandler jsonHandler, RemoteEndpoint remoteEndpoint) {
+		MessageConsumer messageConsumer = wrapMessageConsumer(remoteEndpoint);
+		session.addMessageHandler(new WebSocketMessageHandler(messageConsumer, jsonHandler, remoteEndpoint));
+	}
+	
+}
diff --git a/java/org/eclipse/lsp4j/websocket/WebSocketMessageConsumer.java b/java/org/eclipse/lsp4j/websocket/WebSocketMessageConsumer.java
new file mode 100644
index 0000000..b906567
--- /dev/null
+++ b/java/org/eclipse/lsp4j/websocket/WebSocketMessageConsumer.java
@@ -0,0 +1,71 @@
+/******************************************************************************
+ * Copyright (c) 2019 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.websocket;
+
+import java.io.IOException;
+import java.util.logging.Logger;
+
+import javax.websocket.Session;
+
+import org.eclipse.lsp4j.jsonrpc.JsonRpcException;
+import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
+import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
+import org.eclipse.lsp4j.jsonrpc.messages.Message;
+
+/**
+ * Message consumer that sends messages via a WebSocket session.
+ */
+public class WebSocketMessageConsumer implements MessageConsumer {
+
+	private static final Logger LOG = Logger.getLogger(WebSocketMessageConsumer.class.getName());
+	
+	private final Session session;
+	private final MessageJsonHandler jsonHandler;
+	
+	public WebSocketMessageConsumer(Session session, MessageJsonHandler jsonHandler) {
+		this.session = session;
+		this.jsonHandler = jsonHandler;
+	}
+	
+	public Session getSession() {
+		return session;
+	}
+	
+	@Override
+	public void consume(Message message) {
+		String content = jsonHandler.serialize(message);
+		try {
+			sendMessage(content);
+		} catch (IOException exception) {
+			throw new JsonRpcException(exception);
+		}
+	}
+	
+	protected void sendMessage(String message) throws IOException {
+		if (session.isOpen()) {
+			int length = message.length();
+			if (length <= session.getMaxTextMessageBufferSize()) {
+				session.getAsyncRemote().sendText(message);
+			} else {
+				int currentOffset = 0;
+				while (currentOffset < length) {
+					int currentEnd = Math.min(currentOffset + session.getMaxTextMessageBufferSize(), length);
+					session.getBasicRemote().sendText(message.substring(currentOffset, currentEnd), currentEnd == length);
+					currentOffset = currentEnd;
+				}
+			}
+		} else {
+			LOG.info("Ignoring message due to closed session: " + message);
+		}
+	}
+	
+}
diff --git a/java/org/eclipse/lsp4j/websocket/WebSocketMessageHandler.java b/java/org/eclipse/lsp4j/websocket/WebSocketMessageHandler.java
new file mode 100644
index 0000000..622eef2
--- /dev/null
+++ b/java/org/eclipse/lsp4j/websocket/WebSocketMessageHandler.java
@@ -0,0 +1,47 @@
+/******************************************************************************
+ * Copyright (c) 2019 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.websocket;
+
+import javax.websocket.MessageHandler;
+
+import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
+import org.eclipse.lsp4j.jsonrpc.MessageIssueException;
+import org.eclipse.lsp4j.jsonrpc.MessageIssueHandler;
+import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
+import org.eclipse.lsp4j.jsonrpc.messages.Message;
+
+/**
+ * WebSocket message handler that parses JSON messages and forwards them to a {@link MessageConsumer}.
+ */
+public class WebSocketMessageHandler implements MessageHandler.Whole<String> {
+	
+	private final MessageConsumer callback;
+	private final MessageJsonHandler jsonHandler;
+	private final MessageIssueHandler issueHandler;
+	
+	public WebSocketMessageHandler(MessageConsumer callback, MessageJsonHandler jsonHandler, MessageIssueHandler issueHandler) {
+		this.callback = callback;
+		this.jsonHandler = jsonHandler;
+		this.issueHandler = issueHandler;
+	}
+	
+	public void onMessage(String content) {
+		try {
+			Message message = jsonHandler.parseMessage(content);
+			callback.consume(message);
+		} catch (MessageIssueException exception) {
+			// An issue was found while parsing or validating the message
+			issueHandler.handle(exception.getRpcMessage(), exception.getIssues());
+		}
+	}
+	
+}
diff --git a/java/org/eclipse/lsp4j/websocket/jakarta/WebSocketEndpoint.java b/java/org/eclipse/lsp4j/websocket/jakarta/WebSocketEndpoint.java
new file mode 100644
index 0000000..e0833ce
--- /dev/null
+++ b/java/org/eclipse/lsp4j/websocket/jakarta/WebSocketEndpoint.java
@@ -0,0 +1,51 @@
+/******************************************************************************
+ * Copyright (c) 2019, 2021 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.websocket.jakarta;
+
+import java.util.Collection;
+
+import jakarta.websocket.Endpoint;
+import jakarta.websocket.EndpointConfig;
+import jakarta.websocket.Session;
+
+import org.eclipse.lsp4j.jsonrpc.Launcher;
+
+/**
+ * WebSocket endpoint implementation that connects to a JSON-RPC service.
+ *
+ * @param <T> remote service interface type
+ */
+public abstract class WebSocketEndpoint<T> extends Endpoint {
+	
+	@Override
+	public void onOpen(Session session, EndpointConfig config) {
+		WebSocketLauncherBuilder<T> builder = new WebSocketLauncherBuilder<>();
+		builder.setSession(session);
+		configure(builder);
+		Launcher<T> launcher = builder.create();
+		connect(builder.getLocalServices(), launcher.getRemoteProxy());
+	}
+	
+	/**
+	 * Configure the JSON-RPC launcher. Implementations should set at least the
+	 * {@link Launcher.Builder#setLocalService(Object) local service} and the
+	 * {@link Launcher.Builder#setRemoteInterface(Class) remote interface}.
+	 */
+	protected abstract void configure(Launcher.Builder<T> builder);
+	
+	/**
+	 * Override this in order to connect the local services to the remote service proxy.
+	 */
+	protected void connect(Collection<Object> localServices, T remoteProxy) {
+	}
+	
+}
diff --git a/java/org/eclipse/lsp4j/websocket/jakarta/WebSocketLauncherBuilder.java b/java/org/eclipse/lsp4j/websocket/jakarta/WebSocketLauncherBuilder.java
new file mode 100644
index 0000000..7fdf1e3
--- /dev/null
+++ b/java/org/eclipse/lsp4j/websocket/jakarta/WebSocketLauncherBuilder.java
@@ -0,0 +1,76 @@
+/******************************************************************************
+ * Copyright (c) 2019, 2021 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.websocket.jakarta;
+
+import java.util.Collection;
+
+import jakarta.websocket.Session;
+
+import org.eclipse.lsp4j.jsonrpc.Endpoint;
+import org.eclipse.lsp4j.jsonrpc.Launcher;
+import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
+import org.eclipse.lsp4j.jsonrpc.RemoteEndpoint;
+import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
+import org.eclipse.lsp4j.jsonrpc.services.ServiceEndpoints;
+
+/**
+ * JSON-RPC launcher builder for use in {@link WebSocketEndpoint}.
+ *
+ * @param <T> remote service interface type
+ */
+public class WebSocketLauncherBuilder<T> extends Launcher.Builder<T> {
+	
+	protected Session session;
+	
+	public Collection<Object> getLocalServices() {
+		return localServices;
+	}
+	
+	public WebSocketLauncherBuilder<T> setSession(Session session) {
+		this.session = session;
+		return this;
+	}
+	
+	@Override
+	public Launcher<T> create() {
+		if (localServices == null)
+			throw new IllegalStateException("Local service must be configured.");
+		if (remoteInterfaces == null)
+			throw new IllegalStateException("Remote interface must be configured.");
+		
+		MessageJsonHandler jsonHandler = createJsonHandler();
+		RemoteEndpoint remoteEndpoint = createRemoteEndpoint(jsonHandler);
+		addMessageHandlers(jsonHandler, remoteEndpoint);
+		T remoteProxy = createProxy(remoteEndpoint);
+		return createLauncher(null, remoteProxy, remoteEndpoint, null);
+	}
+	
+	@Override
+	protected RemoteEndpoint createRemoteEndpoint(MessageJsonHandler jsonHandler) {
+		MessageConsumer outgoingMessageStream = new WebSocketMessageConsumer(session, jsonHandler);
+		outgoingMessageStream = wrapMessageConsumer(outgoingMessageStream);
+		Endpoint localEndpoint = ServiceEndpoints.toEndpoint(localServices);
+		RemoteEndpoint remoteEndpoint;
+		if (exceptionHandler == null)
+			remoteEndpoint = new RemoteEndpoint(outgoingMessageStream, localEndpoint);
+		else
+			remoteEndpoint = new RemoteEndpoint(outgoingMessageStream, localEndpoint, exceptionHandler);
+		jsonHandler.setMethodProvider(remoteEndpoint);
+		return remoteEndpoint;
+	}
+	
+	protected void addMessageHandlers(MessageJsonHandler jsonHandler, RemoteEndpoint remoteEndpoint) {
+		MessageConsumer messageConsumer = wrapMessageConsumer(remoteEndpoint);
+		session.addMessageHandler(new WebSocketMessageHandler(messageConsumer, jsonHandler, remoteEndpoint));
+	}
+	
+}
diff --git a/java/org/eclipse/lsp4j/websocket/jakarta/WebSocketMessageConsumer.java b/java/org/eclipse/lsp4j/websocket/jakarta/WebSocketMessageConsumer.java
new file mode 100644
index 0000000..c2eaf16
--- /dev/null
+++ b/java/org/eclipse/lsp4j/websocket/jakarta/WebSocketMessageConsumer.java
@@ -0,0 +1,72 @@
+/******************************************************************************
+ * Copyright (c) 2019, 2021 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.websocket.jakarta;
+
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import jakarta.websocket.Session;
+
+import org.eclipse.lsp4j.jsonrpc.JsonRpcException;
+import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
+import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
+import org.eclipse.lsp4j.jsonrpc.messages.Message;
+
+/**
+ * Message consumer that sends messages via a WebSocket session.
+ */
+public class WebSocketMessageConsumer implements MessageConsumer {
+
+	private static final Logger LOG = Logger.getLogger(WebSocketMessageConsumer.class.getName());
+	
+	private final Session session;
+	private final MessageJsonHandler jsonHandler;
+	
+	public WebSocketMessageConsumer(Session session, MessageJsonHandler jsonHandler) {
+		this.session = session;
+		this.jsonHandler = jsonHandler;
+	}
+	
+	public Session getSession() {
+		return session;
+	}
+	
+	@Override
+	public void consume(Message message) {
+		String content = jsonHandler.serialize(message);
+		try {
+			sendMessage(content);
+		} catch (IOException exception) {
+			throw new JsonRpcException(exception);
+		}
+	}
+	
+	protected void sendMessage(String message) throws IOException {
+		if (session.isOpen()) {
+			int length = message.length();
+			if (length <= session.getMaxTextMessageBufferSize()) {
+				session.getAsyncRemote().sendText(message);
+			} else {
+				int currentOffset = 0;
+				while (currentOffset < length) {
+					int currentEnd = Math.min(currentOffset + session.getMaxTextMessageBufferSize(), length);
+					session.getBasicRemote().sendText(message.substring(currentOffset, currentEnd), currentEnd == length);
+					currentOffset = currentEnd;
+				}
+			}
+		} else {
+			LOG.log(Level.INFO, "Ignoring message due to closed session: {0}", message);
+		}
+	}
+	
+}
diff --git a/java/org/eclipse/lsp4j/websocket/jakarta/WebSocketMessageHandler.java b/java/org/eclipse/lsp4j/websocket/jakarta/WebSocketMessageHandler.java
new file mode 100644
index 0000000..686987b
--- /dev/null
+++ b/java/org/eclipse/lsp4j/websocket/jakarta/WebSocketMessageHandler.java
@@ -0,0 +1,47 @@
+/******************************************************************************
+ * Copyright (c) 2019, 2021 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.websocket.jakarta;
+
+import jakarta.websocket.MessageHandler;
+
+import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
+import org.eclipse.lsp4j.jsonrpc.MessageIssueException;
+import org.eclipse.lsp4j.jsonrpc.MessageIssueHandler;
+import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
+import org.eclipse.lsp4j.jsonrpc.messages.Message;
+
+/**
+ * WebSocket message handler that parses JSON messages and forwards them to a {@link MessageConsumer}.
+ */
+public class WebSocketMessageHandler implements MessageHandler.Whole<String> {
+	
+	private final MessageConsumer callback;
+	private final MessageJsonHandler jsonHandler;
+	private final MessageIssueHandler issueHandler;
+	
+	public WebSocketMessageHandler(MessageConsumer callback, MessageJsonHandler jsonHandler, MessageIssueHandler issueHandler) {
+		this.callback = callback;
+		this.jsonHandler = jsonHandler;
+		this.issueHandler = issueHandler;
+	}
+	
+	public void onMessage(String content) {
+		try {
+			Message message = jsonHandler.parseMessage(content);
+			callback.consume(message);
+		} catch (MessageIssueException exception) {
+			// An issue was found while parsing or validating the message
+			issueHandler.handle(exception.getRpcMessage(), exception.getIssues());
+		}
+	}
+	
+}
diff --git a/javatests/org/eclipse/lsp4j/EqualityTest.java b/javatests/org/eclipse/lsp4j/EqualityTest.java
new file mode 100644
index 0000000..444c05c
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/EqualityTest.java
@@ -0,0 +1,49 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.test;
+
+import java.util.ArrayList;
+
+import org.eclipse.lsp4j.CompletionItem;
+import org.eclipse.lsp4j.Position;
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.TextEdit;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class EqualityTest {
+
+	@Test public void testEquals() {
+		Assert.assertEquals(new TextDocumentIdentifier("foo"), new TextDocumentIdentifier("foo"));
+		Assert.assertNotEquals(new TextDocumentIdentifier("foo"), new TextDocumentIdentifier("bar"));
+		
+		CompletionItem e1 = new CompletionItem();
+		e1.setAdditionalTextEdits(new ArrayList<>());
+		e1.getAdditionalTextEdits().add(new TextEdit(new Range(new Position(1,1), new Position(1,1)), "foo"));
+		
+		CompletionItem e2 = new CompletionItem();
+		e2.setAdditionalTextEdits(new ArrayList<>());
+		e2.getAdditionalTextEdits().add(new TextEdit(new Range(new Position(1,1), new Position(1,1)), "foo"));
+		
+		CompletionItem e3 = new CompletionItem();
+		e3.setAdditionalTextEdits(new ArrayList<>());
+		e3.getAdditionalTextEdits().add(new TextEdit(new Range(new Position(1,1), new Position(1,2)), "foo"));
+		
+		Assert.assertEquals(e1, e2);
+		Assert.assertNotEquals(e1, e3);
+		
+		Assert.assertEquals(e1.hashCode(), e2.hashCode());
+		Assert.assertNotEquals(e1.hashCode(), e3.hashCode());
+	}
+	
+}
diff --git a/javatests/org/eclipse/lsp4j/LSPEndpointTest.xtend b/javatests/org/eclipse/lsp4j/LSPEndpointTest.xtend
new file mode 100644
index 0000000..1783632
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/LSPEndpointTest.xtend
@@ -0,0 +1,142 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.test
+
+import java.io.ByteArrayOutputStream
+import java.io.OutputStreamWriter
+import java.io.PipedInputStream
+import java.io.PipedOutputStream
+import java.util.concurrent.CompletableFuture
+import java.util.concurrent.CompletionException
+import java.util.concurrent.TimeUnit
+import org.eclipse.lsp4j.DidChangeConfigurationParams
+import org.eclipse.lsp4j.DidChangeTextDocumentParams
+import org.eclipse.lsp4j.DidChangeWatchedFilesParams
+import org.eclipse.lsp4j.DidCloseTextDocumentParams
+import org.eclipse.lsp4j.DidOpenTextDocumentParams
+import org.eclipse.lsp4j.DidSaveTextDocumentParams
+import org.eclipse.lsp4j.HoverParams
+import org.eclipse.lsp4j.InitializeParams
+import org.eclipse.lsp4j.MessageParams
+import org.eclipse.lsp4j.Position
+import org.eclipse.lsp4j.PublishDiagnosticsParams
+import org.eclipse.lsp4j.ShowDocumentParams;
+import org.eclipse.lsp4j.ShowMessageRequestParams
+import org.eclipse.lsp4j.TextDocumentIdentifier
+import org.eclipse.lsp4j.jsonrpc.services.GenericEndpoint
+import org.eclipse.lsp4j.launch.LSPLauncher
+import org.eclipse.lsp4j.services.LanguageClient
+import org.eclipse.lsp4j.services.LanguageServer
+import org.eclipse.lsp4j.services.TextDocumentService
+import org.eclipse.lsp4j.services.WorkspaceService
+import org.eclipse.xtend.lib.annotations.Accessors
+import org.junit.Test
+
+import static org.junit.Assert.*
+
+class LSPEndpointTest {
+
+	static val TIMEOUT = 2000
+
+	@Test
+	def void testIssue152() throws Exception {
+		val client = new DummyClient
+		val in = new PipedInputStream
+		val responseStream = new PipedOutputStream
+		in.connect(responseStream)
+		val responseWriter = new OutputStreamWriter(responseStream)
+		val out = new ByteArrayOutputStream
+		val launcher = LSPLauncher.createClientLauncher(client, in, out, true, null)
+		val future = launcher.startListening()
+
+		val hoverResult = launcher.remoteProxy.textDocumentService.hover(new HoverParams => [
+			textDocument = new TextDocumentIdentifier('foo')
+			position = new Position(0, 0)
+		])
+		responseWriter.write('Content-Length: 60\r\n\r\n')
+		responseWriter.write('{"jsonrpc":"2.0","id":"1","result":{"contents":[null,null]}}')
+		responseWriter.flush()
+
+		try {
+			hoverResult.join()
+			fail('Expected a CompletionException to be thrown.')
+		} catch (CompletionException exception) {
+			assertEquals('''
+				Lists must not contain null references. Path: $.result.contents[0]
+				Lists must not contain null references. Path: $.result.contents[1]
+			'''.toString.replaceAll("\\r", "").trim, exception.cause.message)
+			assertFalse(future.isDone)
+		} finally {
+			in.close()
+		}
+	}
+
+	@Test
+	def void testIssue346() throws Exception {
+		val logMessages = new LogMessageAccumulator
+		try {
+			logMessages.registerTo(GenericEndpoint)
+
+			val server = new DummyServer
+			val in = new PipedInputStream
+			val messageStream = new PipedOutputStream
+			in.connect(messageStream)
+			val messageWriter = new OutputStreamWriter(messageStream)
+			val out = new ByteArrayOutputStream
+			val launcher = LSPLauncher.createServerLauncher(server, in, out, true, null)
+			launcher.startListening()
+
+			messageWriter.write('Content-Length: 48\r\n\r\n')
+			messageWriter.write('{"jsonrpc": "2.0","method": "exit","params": {}}')
+			messageWriter.flush()
+
+			server.exited.get(TIMEOUT, TimeUnit.MILLISECONDS)
+			assertTrue(logMessages.records.join('\n', [message]), logMessages.records.isEmpty)
+		} finally {
+			logMessages.unregister();
+		}
+	}
+
+	@Accessors
+	private static class DummyServer implements LanguageServer {
+
+		val textDocumentService = new TextDocumentService {
+			override didChange(DidChangeTextDocumentParams params) {}
+			override didClose(DidCloseTextDocumentParams params) {}
+			override didOpen(DidOpenTextDocumentParams params) {}
+			override didSave(DidSaveTextDocumentParams params) {}
+		}
+
+		val workspaceService = new WorkspaceService {
+			override didChangeConfiguration(DidChangeConfigurationParams params) {}
+			override didChangeWatchedFiles(DidChangeWatchedFilesParams params) {}
+		}
+
+		override initialize(InitializeParams params) {}
+		override shutdown() {}
+
+		val exited = new CompletableFuture<Void>
+		override exit() {
+			exited.complete(null)
+		}
+	}
+
+	private static class DummyClient implements LanguageClient {
+		override logMessage(MessageParams message) {}
+		override publishDiagnostics(PublishDiagnosticsParams diagnostics) {}
+		override showMessage(MessageParams messageParams) {}
+		override showMessageRequest(ShowMessageRequestParams requestParams) {}
+		override showDocument(ShowDocumentParams requestParams) {}
+		override telemetryEvent(Object object) {}
+	}
+
+}
\ No newline at end of file
diff --git a/javatests/org/eclipse/lsp4j/LogMessageAccumulator.java b/javatests/org/eclipse/lsp4j/LogMessageAccumulator.java
new file mode 100644
index 0000000..4c3eb87
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/LogMessageAccumulator.java
@@ -0,0 +1,111 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Predicate;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import org.junit.Assert;
+
+public class LogMessageAccumulator extends Handler {
+	
+	private static final long TIMEOUT = 2000;
+	
+	private final List<LogRecord> records = new ArrayList<>();
+	private final List<Logger> registeredLoggers = new ArrayList<>();
+	
+	public Logger registerTo(Class<?> clazz) {
+		return registerTo(clazz.getName());
+	}
+	
+	public Logger registerTo(String name) {
+		Logger logger = Logger.getLogger(name);
+		logger.setUseParentHandlers(false);
+		logger.addHandler(this);
+		logger.setLevel(Level.ALL);
+		registeredLoggers.add(logger);
+		return logger;
+	}
+	
+	public void unregister() {
+		for (Logger logger : registeredLoggers) {
+			logger.setLevel(null);
+			logger.removeHandler(this);
+			logger.setUseParentHandlers(true);
+		}
+		registeredLoggers.clear();
+	}
+	
+	public List<LogRecord> getRecords() {
+		return records;
+	}
+	
+	public LogRecord findRecord(Level level, String message) {
+		synchronized (records) {
+			for (LogRecord r : records) {
+				if (level.equals(r.getLevel()) && message.equals(r.getMessage()))
+					return r;
+			}
+			return null;
+		}
+	}
+	
+	public Optional<LogRecord> match(Predicate<LogRecord> predicate) {
+		synchronized (records) {
+			return records.stream().filter(predicate).findFirst();
+		}
+	} 
+
+	@Override
+	public void publish(LogRecord record) {
+		synchronized (records) {
+			records.add(record);
+		}
+	}
+
+	@Override
+	public void flush() {
+	}
+
+	@Override
+	public void close() throws SecurityException {
+	}
+
+	public void await(Predicate<LogRecord> predicate) throws InterruptedException {
+		long startTime = System.currentTimeMillis();
+		while (!match(predicate).isPresent()) {
+			Thread.sleep(20);
+			if (System.currentTimeMillis() - startTime > TIMEOUT) {
+				synchronized (records) {
+					String records = this.records.stream().map(r -> r.getLevel() + ": " + r.getMessage()).reduce((a, a2) -> a + '\n' + a2).get();
+					Assert.fail("Timeout elapsed while waiting for logging, logged:\n" + records);
+				}
+			}
+		}
+	}
+	
+	public void await(Level level, String message) throws InterruptedException {
+		long startTime = System.currentTimeMillis();
+		while (findRecord(level, message) == null) {
+			Thread.sleep(20);
+			if (System.currentTimeMillis() - startTime > TIMEOUT)
+				Assert.fail("Timeout elapsed while waiting for " + level + ": " + message);
+		}
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/NoAnnotationTest.xtend b/javatests/org/eclipse/lsp4j/NoAnnotationTest.xtend
new file mode 100644
index 0000000..f36d443
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/NoAnnotationTest.xtend
@@ -0,0 +1,25 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.test
+
+import org.eclipse.lsp4j.CodeLens
+import org.eclipse.lsp4j.generator.JsonRpcData
+import org.junit.Assert
+import org.junit.Test
+
+class NoAnnotationTest {
+    
+    @Test def void testNoAnnotation() {
+        Assert.assertFalse(CodeLens.annotations.exists[annotationType == JsonRpcData])
+    }
+    
+}
\ No newline at end of file
diff --git a/javatests/org/eclipse/lsp4j/NonNullTest.java b/javatests/org/eclipse/lsp4j/NonNullTest.java
new file mode 100644
index 0000000..ba56c38
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/NonNullTest.java
@@ -0,0 +1,32 @@
+package org.eclipse.lsp4j.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.eclipse.lsp4j.CodeAction;
+import org.junit.Test;
+
+public class NonNullTest {
+	
+	@Test
+	public void testCodeAction1() {
+		try {
+			new CodeAction(null);
+			fail("Expected a NullPointerException");
+		} catch (NullPointerException exc) {
+			assertEquals("Property must not be null: title", exc.getMessage());
+		}
+	}
+	
+	@Test
+	public void testCodeAction2() {
+		try {
+			CodeAction codeAction = new CodeAction();
+			codeAction.setTitle(null);
+			fail("Expected a NullPointerException");
+		} catch (NullPointerException exc) {
+			assertEquals("Property must not be null: title", exc.getMessage());
+		}
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/debug/test/DSPDebugServer.java b/javatests/org/eclipse/lsp4j/debug/test/DSPDebugServer.java
new file mode 100644
index 0000000..b02d876
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/debug/test/DSPDebugServer.java
@@ -0,0 +1,35 @@
+/******************************************************************************
+ * Copyright (c) 2018 Kichwa Coders and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.debug.test;
+
+import java.io.IOException;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.util.concurrent.Future;
+
+import org.eclipse.lsp4j.debug.launch.DSPLauncher;
+import org.eclipse.lsp4j.debug.services.IDebugProtocolClient;
+import org.eclipse.lsp4j.jsonrpc.Launcher;
+import org.junit.Test;
+
+public class DSPDebugServer {
+
+	// This is a test for https://github.com/eclipse/lsp4j/issues/224
+	@Test
+	public void testDebugServerCanBeLaunched() throws IOException {
+		TestDebugServer testDebugServer = new TestDebugServer();
+		Launcher<IDebugProtocolClient> launcher = DSPLauncher.createServerLauncher(testDebugServer,
+				new PipedInputStream(), new PipedOutputStream());
+		Future<Void> listening = launcher.startListening();
+		listening.cancel(true);
+	}
+}
diff --git a/javatests/org/eclipse/lsp4j/debug/test/DSPLauncherTest.java b/javatests/org/eclipse/lsp4j/debug/test/DSPLauncherTest.java
new file mode 100644
index 0000000..88d97e3
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/debug/test/DSPLauncherTest.java
@@ -0,0 +1,161 @@
+/******************************************************************************
+ * Copyright (c) 2016-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.debug.test;
+
+import java.io.IOException;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.eclipse.lsp4j.debug.Capabilities;
+import org.eclipse.lsp4j.debug.InitializeRequestArguments;
+import org.eclipse.lsp4j.debug.OutputEventArguments;
+import org.eclipse.lsp4j.debug.launch.DSPLauncher;
+import org.eclipse.lsp4j.debug.services.IDebugProtocolClient;
+import org.eclipse.lsp4j.debug.services.IDebugProtocolServer;
+import org.eclipse.lsp4j.jsonrpc.Endpoint;
+import org.eclipse.lsp4j.jsonrpc.Launcher;
+import org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer;
+import org.eclipse.lsp4j.jsonrpc.services.ServiceEndpoints;
+import org.eclipse.xtext.xbase.lib.Pair;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class DSPLauncherTest {
+
+	private static final long TIMEOUT = 2000;
+
+	@Test
+	public void testNotification() throws IOException {
+		OutputEventArguments p = new OutputEventArguments();
+		p.setOutput("Hello World");
+
+		client.expectedNotifications.put("output", p);
+		serverLauncher.getRemoteProxy().output(p);
+		client.joinOnEmpty();
+	}
+
+	@Test
+	public void testRequest() throws Exception {
+		InitializeRequestArguments p = new InitializeRequestArguments();
+		p.setClientID("test");
+
+		Capabilities result = new Capabilities();
+		result.setSupportTerminateDebuggee(true);
+		result.setSupportsCompletionsRequest(false);
+
+		server.expectedRequests.put("initialize", new Pair<>(p, result));
+		CompletableFuture<Capabilities> future = clientLauncher.getRemoteProxy().initialize(p);
+		Assert.assertEquals(result.toString(), future.get(TIMEOUT, TimeUnit.MILLISECONDS).toString());
+		client.joinOnEmpty();
+	}
+
+	static class AssertingEndpoint implements Endpoint {
+		public Map<String, Pair<Object, Object>> expectedRequests = new LinkedHashMap<>();
+
+		@Override
+		public CompletableFuture<?> request(String method, Object parameter) {
+			Assert.assertTrue(expectedRequests.containsKey(method));
+			Pair<Object, Object> result = expectedRequests.remove(method);
+			Assert.assertEquals(result.getKey().toString(), parameter.toString());
+			return CompletableFuture.completedFuture(result.getValue());
+		}
+
+		public Map<String, Object> expectedNotifications = new LinkedHashMap<>();
+
+		@Override
+		public void notify(String method, Object parameter) {
+			Assert.assertTrue(expectedNotifications.containsKey(method));
+			Object object = expectedNotifications.remove(method);
+			Assert.assertEquals(object.toString(), parameter.toString());
+		}
+
+		/**
+		 * wait max 1 sec for all expectations to be removed
+		 */
+		public void joinOnEmpty() {
+			long before = System.currentTimeMillis();
+			do {
+				if (expectedNotifications.isEmpty() && expectedNotifications.isEmpty()) {
+					return;
+				}
+				try {
+					Thread.sleep(100);
+				} catch (InterruptedException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			} while (System.currentTimeMillis() < before + 1000);
+			Assert.fail("expectations weren't empty " + toString());
+		}
+
+		@Override
+		public String toString() {
+			return new ToStringBuilder(this).addAllFields().toString();
+		}
+
+	}
+
+	private AssertingEndpoint server;
+	private Launcher<IDebugProtocolClient> serverLauncher;
+	private Future<?> serverListening;
+
+	private AssertingEndpoint client;
+	private Launcher<IDebugProtocolServer> clientLauncher;
+	private Future<?> clientListening;
+
+	private Level logLevel;
+
+	@Before
+	public void setup() throws IOException {
+		PipedInputStream inClient = new PipedInputStream();
+		PipedOutputStream outClient = new PipedOutputStream();
+		PipedInputStream inServer = new PipedInputStream();
+		PipedOutputStream outServer = new PipedOutputStream();
+
+		inClient.connect(outServer);
+		outClient.connect(inServer);
+		server = new AssertingEndpoint();
+		serverLauncher = DSPLauncher.createServerLauncher(
+				ServiceEndpoints.toServiceObject(server, IDebugProtocolServer.class), inServer, outServer);
+		serverListening = serverLauncher.startListening();
+
+		client = new AssertingEndpoint();
+		clientLauncher = DSPLauncher.createClientLauncher(
+				ServiceEndpoints.toServiceObject(client, IDebugProtocolClient.class), inClient, outClient);
+		clientListening = clientLauncher.startListening();
+
+		Logger logger = Logger.getLogger(StreamMessageProducer.class.getName());
+		logLevel = logger.getLevel();
+		logger.setLevel(Level.SEVERE);
+	}
+
+	@After
+	public void teardown() throws InterruptedException, ExecutionException {
+		clientListening.cancel(true);
+		serverListening.cancel(true);
+		Thread.sleep(10);
+		Logger logger = Logger.getLogger(StreamMessageProducer.class.getName());
+		logger.setLevel(logLevel);
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/debug/test/DebugProtocolTest.java b/javatests/org/eclipse/lsp4j/debug/test/DebugProtocolTest.java
new file mode 100644
index 0000000..67131ce
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/debug/test/DebugProtocolTest.java
@@ -0,0 +1,21 @@
+/******************************************************************************
+ * Copyright (c) 2017 Kichwa Coders Ltd. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.debug.test;
+
+import org.junit.Test;
+
+public class DebugProtocolTest {
+	@Test
+	public void test() {
+		// No tests as of now because there is no logic code in this plug-in yet.
+	}
+}
diff --git a/javatests/org/eclipse/lsp4j/debug/test/TestDebugServer.java b/javatests/org/eclipse/lsp4j/debug/test/TestDebugServer.java
new file mode 100644
index 0000000..34075d6
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/debug/test/TestDebugServer.java
@@ -0,0 +1,263 @@
+package org.eclipse.lsp4j.debug.test;
+
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+
+import org.eclipse.lsp4j.debug.Capabilities;
+import org.eclipse.lsp4j.debug.CompletionsArguments;
+import org.eclipse.lsp4j.debug.CompletionsResponse;
+import org.eclipse.lsp4j.debug.ConfigurationDoneArguments;
+import org.eclipse.lsp4j.debug.ContinueArguments;
+import org.eclipse.lsp4j.debug.ContinueResponse;
+import org.eclipse.lsp4j.debug.DataBreakpointInfoArguments;
+import org.eclipse.lsp4j.debug.DataBreakpointInfoResponse;
+import org.eclipse.lsp4j.debug.DisassembleArguments;
+import org.eclipse.lsp4j.debug.DisassembleResponse;
+import org.eclipse.lsp4j.debug.DisconnectArguments;
+import org.eclipse.lsp4j.debug.EvaluateArguments;
+import org.eclipse.lsp4j.debug.EvaluateResponse;
+import org.eclipse.lsp4j.debug.ExceptionInfoArguments;
+import org.eclipse.lsp4j.debug.ExceptionInfoResponse;
+import org.eclipse.lsp4j.debug.GotoArguments;
+import org.eclipse.lsp4j.debug.GotoTargetsArguments;
+import org.eclipse.lsp4j.debug.GotoTargetsResponse;
+import org.eclipse.lsp4j.debug.InitializeRequestArguments;
+import org.eclipse.lsp4j.debug.LoadedSourcesArguments;
+import org.eclipse.lsp4j.debug.LoadedSourcesResponse;
+import org.eclipse.lsp4j.debug.ModulesArguments;
+import org.eclipse.lsp4j.debug.ModulesResponse;
+import org.eclipse.lsp4j.debug.NextArguments;
+import org.eclipse.lsp4j.debug.PauseArguments;
+import org.eclipse.lsp4j.debug.ReadMemoryArguments;
+import org.eclipse.lsp4j.debug.ReadMemoryResponse;
+import org.eclipse.lsp4j.debug.RestartArguments;
+import org.eclipse.lsp4j.debug.RestartFrameArguments;
+import org.eclipse.lsp4j.debug.ReverseContinueArguments;
+import org.eclipse.lsp4j.debug.RunInTerminalRequestArguments;
+import org.eclipse.lsp4j.debug.RunInTerminalResponse;
+import org.eclipse.lsp4j.debug.ScopesArguments;
+import org.eclipse.lsp4j.debug.ScopesResponse;
+import org.eclipse.lsp4j.debug.SetBreakpointsArguments;
+import org.eclipse.lsp4j.debug.SetBreakpointsResponse;
+import org.eclipse.lsp4j.debug.SetDataBreakpointsArguments;
+import org.eclipse.lsp4j.debug.SetDataBreakpointsResponse;
+import org.eclipse.lsp4j.debug.SetExceptionBreakpointsArguments;
+import org.eclipse.lsp4j.debug.SetExpressionArguments;
+import org.eclipse.lsp4j.debug.SetExpressionResponse;
+import org.eclipse.lsp4j.debug.SetFunctionBreakpointsArguments;
+import org.eclipse.lsp4j.debug.SetFunctionBreakpointsResponse;
+import org.eclipse.lsp4j.debug.SetVariableArguments;
+import org.eclipse.lsp4j.debug.SetVariableResponse;
+import org.eclipse.lsp4j.debug.SourceArguments;
+import org.eclipse.lsp4j.debug.SourceResponse;
+import org.eclipse.lsp4j.debug.StackTraceArguments;
+import org.eclipse.lsp4j.debug.StackTraceResponse;
+import org.eclipse.lsp4j.debug.StepBackArguments;
+import org.eclipse.lsp4j.debug.StepInArguments;
+import org.eclipse.lsp4j.debug.StepInTargetsArguments;
+import org.eclipse.lsp4j.debug.StepInTargetsResponse;
+import org.eclipse.lsp4j.debug.StepOutArguments;
+import org.eclipse.lsp4j.debug.TerminateArguments;
+import org.eclipse.lsp4j.debug.TerminateThreadsArguments;
+import org.eclipse.lsp4j.debug.ThreadsResponse;
+import org.eclipse.lsp4j.debug.VariablesArguments;
+import org.eclipse.lsp4j.debug.VariablesResponse;
+import org.eclipse.lsp4j.debug.services.IDebugProtocolServer;
+
+public class TestDebugServer implements IDebugProtocolServer {
+	@Override
+	public CompletableFuture<RunInTerminalResponse> runInTerminal(RunInTerminalRequestArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<Capabilities> initialize(InitializeRequestArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<Void> configurationDone(ConfigurationDoneArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<Void> launch(Map<String, Object> args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<Void> attach(Map<String, Object> args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<Void> restart(RestartArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<Void> disconnect(DisconnectArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<SetBreakpointsResponse> setBreakpoints(SetBreakpointsArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<SetFunctionBreakpointsResponse> setFunctionBreakpoints(
+			SetFunctionBreakpointsArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<Void> setExceptionBreakpoints(SetExceptionBreakpointsArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<DataBreakpointInfoResponse> dataBreakpointInfo(DataBreakpointInfoArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<SetDataBreakpointsResponse> setDataBreakpoints(SetDataBreakpointsArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<ContinueResponse> continue_(ContinueArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<Void> next(NextArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<Void> stepIn(StepInArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<Void> stepOut(StepOutArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<Void> stepBack(StepBackArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<Void> reverseContinue(ReverseContinueArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<Void> restartFrame(RestartFrameArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<Void> goto_(GotoArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<Void> pause(PauseArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<StackTraceResponse> stackTrace(StackTraceArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<ScopesResponse> scopes(ScopesArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<VariablesResponse> variables(VariablesArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<SetVariableResponse> setVariable(SetVariableArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<SourceResponse> source(SourceArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<ThreadsResponse> threads() {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<ModulesResponse> modules(ModulesArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<LoadedSourcesResponse> loadedSources(LoadedSourcesArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<EvaluateResponse> evaluate(EvaluateArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<StepInTargetsResponse> stepInTargets(StepInTargetsArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<GotoTargetsResponse> gotoTargets(GotoTargetsArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<CompletionsResponse> completions(CompletionsArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<ExceptionInfoResponse> exceptionInfo(ExceptionInfoArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<Void> terminate(TerminateArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<Void> terminateThreads(TerminateThreadsArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<SetExpressionResponse> setExpression(SetExpressionArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<ReadMemoryResponse> readMemory(ReadMemoryArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+
+	@Override
+	public CompletableFuture<DisassembleResponse> disassemble(DisassembleArguments args) {
+		return CompletableFuture.completedFuture(null);
+	}
+}
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/debug/test/DebugIntegrationTest.java b/javatests/org/eclipse/lsp4j/jsonrpc/debug/test/DebugIntegrationTest.java
new file mode 100644
index 0000000..891d92d
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/debug/test/DebugIntegrationTest.java
@@ -0,0 +1,481 @@
+/******************************************************************************
+ * Copyright (c) 2016-2017 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.debug.test;
+
+import static org.eclipse.lsp4j.jsonrpc.json.MessageConstants.CONTENT_LENGTH_HEADER;
+import static org.eclipse.lsp4j.jsonrpc.json.MessageConstants.CRLF;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.eclipse.lsp4j.jsonrpc.CompletableFutures;
+import org.eclipse.lsp4j.jsonrpc.Launcher;
+import org.eclipse.lsp4j.jsonrpc.RemoteEndpoint;
+import org.eclipse.lsp4j.jsonrpc.ResponseErrorException;
+import org.eclipse.lsp4j.jsonrpc.debug.DebugLauncher;
+import org.eclipse.lsp4j.jsonrpc.services.GenericEndpoint;
+import org.eclipse.lsp4j.jsonrpc.services.JsonNotification;
+import org.eclipse.lsp4j.jsonrpc.services.JsonRequest;
+import org.eclipse.lsp4j.jsonrpc.validation.ReflectiveMessageValidator;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class DebugIntegrationTest {
+
+	private static final long TIMEOUT = 2000;
+
+	public static class MyParam {
+		public MyParam(String string) {
+			this.value = string;
+		}
+
+		String value;
+	}
+
+	public static interface MyServer {
+		@JsonRequest
+		CompletableFuture<MyParam> askServer(MyParam param);
+	}
+
+	public static interface MyClient {
+		@JsonRequest
+		CompletableFuture<MyParam> askClient(MyParam param);
+	}
+
+	@Test
+	public void testBothDirectionRequests() throws Exception {
+		// create client side
+		PipedInputStream in = new PipedInputStream();
+		PipedOutputStream out = new PipedOutputStream();
+		PipedInputStream in2 = new PipedInputStream();
+		PipedOutputStream out2 = new PipedOutputStream();
+
+		in.connect(out2);
+		out.connect(in2);
+
+		MyClient client = new MyClient() {
+			@Override
+			public CompletableFuture<MyParam> askClient(MyParam param) {
+				return CompletableFuture.completedFuture(param);
+			}
+		};
+		Launcher<MyServer> clientSideLauncher = DebugLauncher.createLauncher(client, MyServer.class, in, out);
+
+		// create server side
+		MyServer server = new MyServer() {
+			@Override
+			public CompletableFuture<MyParam> askServer(MyParam param) {
+				return CompletableFuture.completedFuture(param);
+			}
+		};
+		Launcher<MyClient> serverSideLauncher = DebugLauncher.createLauncher(server, MyClient.class, in2, out2);
+
+		clientSideLauncher.startListening();
+		serverSideLauncher.startListening();
+
+		CompletableFuture<MyParam> fooFuture = clientSideLauncher.getRemoteProxy().askServer(new MyParam("FOO"));
+		CompletableFuture<MyParam> barFuture = serverSideLauncher.getRemoteProxy().askClient(new MyParam("BAR"));
+
+		Assert.assertEquals("FOO", fooFuture.get(TIMEOUT, TimeUnit.MILLISECONDS).value);
+		Assert.assertEquals("BAR", barFuture.get(TIMEOUT, TimeUnit.MILLISECONDS).value);
+	}
+
+	@Test
+	public void testCancellation() throws Exception {
+		// create client side
+		PipedInputStream in = new PipedInputStream();
+		PipedOutputStream out = new PipedOutputStream();
+		PipedInputStream in2 = new PipedInputStream();
+		PipedOutputStream out2 = new PipedOutputStream();
+
+		in.connect(out2);
+		out.connect(in2);
+
+		boolean[] inComputeAsync = new boolean[1];
+		boolean[] cancellationHappened = new boolean[1];
+
+		MyClient client = new MyClient() {
+			@Override
+			public CompletableFuture<MyParam> askClient(MyParam param) {
+				return CompletableFutures.computeAsync(cancelToken -> {
+					try {
+						long startTime = System.currentTimeMillis();
+						inComputeAsync[0] = true;
+						do {
+							cancelToken.checkCanceled();
+							Thread.sleep(50);
+						} while (System.currentTimeMillis() - startTime < TIMEOUT);
+					} catch (CancellationException e) {
+						cancellationHappened[0] = true;
+					} catch (InterruptedException e) {
+						Assert.fail("Thread was interrupted unexpectedly.");
+					}
+					return param;
+				});
+			}
+		};
+		Launcher<MyServer> clientSideLauncher = DebugLauncher.createLauncher(client, MyServer.class, in, out);
+
+		// create server side
+		MyServer server = new MyServer() {
+			@Override
+			public CompletableFuture<MyParam> askServer(MyParam param) {
+				return CompletableFuture.completedFuture(param);
+			}
+		};
+		Launcher<MyClient> serverSideLauncher = DebugLauncher.createLauncher(server, MyClient.class, in2, out2);
+
+		clientSideLauncher.startListening();
+		serverSideLauncher.startListening();
+
+		CompletableFuture<MyParam> future = serverSideLauncher.getRemoteProxy().askClient(new MyParam("FOO"));
+
+		long startTime = System.currentTimeMillis();
+		while (!inComputeAsync[0]) {
+			Thread.sleep(50);
+			if (System.currentTimeMillis() - startTime > TIMEOUT)
+				Assert.fail("Timeout waiting for client to start computing.");
+		}
+		future.cancel(true);
+
+		startTime = System.currentTimeMillis();
+		while (!cancellationHappened[0]) {
+			Thread.sleep(50);
+			if (System.currentTimeMillis() - startTime > TIMEOUT)
+				Assert.fail("Timeout waiting for confirmation of cancellation.");
+		}
+		try {
+			future.get(TIMEOUT, TimeUnit.MILLISECONDS);
+			Assert.fail("Expected cancellation.");
+		} catch (CancellationException e) {
+		}
+	}
+
+	@Test
+	public void testCancellationResponse() throws Exception {
+		// create client messages
+		String requestMessage = "{\"type\":\"request\","
+				+ "\"seq\":1,\n"
+				+ "\"command\":\"askServer\",\n"
+				+ "\"arguments\": { value: \"bar\" }\n"
+				+ "}";
+		String cancellationMessage = "{\"type\":\"event\","
+				+ "\"event\":\"$/cancelRequest\",\n"
+				+ "\"body\": { id: 1 }\n"
+				+ "}";
+		String clientMessages = getHeader(requestMessage.getBytes().length) + requestMessage
+				+ getHeader(cancellationMessage.getBytes().length) + cancellationMessage;
+
+		// create server side
+		ByteArrayInputStream in = new ByteArrayInputStream(clientMessages.getBytes());
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		MyServer server = new MyServer() {
+			@Override
+			public CompletableFuture<MyParam> askServer(MyParam param) {
+				return CompletableFutures.computeAsync(cancelToken -> {
+					try {
+						long startTime = System.currentTimeMillis();
+						do {
+							cancelToken.checkCanceled();
+							Thread.sleep(50);
+						} while (System.currentTimeMillis() - startTime < TIMEOUT);
+					} catch (InterruptedException e) {
+						Assert.fail("Thread was interrupted unexpectedly.");
+					}
+					return param;
+				});
+			}
+		};
+		Launcher<MyClient> serverSideLauncher = DebugLauncher.createLauncher(server, MyClient.class, in, out);
+		serverSideLauncher.startListening().get(TIMEOUT, TimeUnit.MILLISECONDS);
+
+		Assert.assertEquals("Content-Length: 163\r\n\r\n" +
+				"{\"type\":\"response\",\"seq\":1,\"request_seq\":1,\"command\":\"askServer\",\"success\":false,\"message\":\"The request (id: 1, method: \\u0027askServer\\u0027) has been cancelled\"}",
+				out.toString());
+	}
+
+
+	@Test
+	public void testVersatility() throws Exception {
+		Logger.getLogger(RemoteEndpoint.class.getName()).setLevel(Level.OFF);
+		// create client side
+		PipedInputStream in = new PipedInputStream();
+		PipedOutputStream out = new PipedOutputStream();
+		PipedInputStream in2 = new PipedInputStream();
+		PipedOutputStream out2 = new PipedOutputStream();
+
+		// See https://github.com/eclipse/lsp4j/issues/510 for full details.
+		// Make sure that the thread that writes to the PipedOutputStream stays alive
+		// until the read from the PipedInputStream. Using a cached thread pool
+		// does not 100% guarantee that, but increases the probability that the
+		// selected thread will exist for the lifetime of the test.
+		ExecutorService executor = Executors.newCachedThreadPool();
+
+		in.connect(out2);
+		out.connect(in2);
+
+		MyClient client = new MyClient() {
+			private int tries = 0;
+
+			@Override
+			public CompletableFuture<MyParam> askClient(MyParam param) {
+				if (tries == 0) {
+					tries++;
+					throw new UnsupportedOperationException();
+				}
+				return CompletableFutures.computeAsync(executor, cancelToken -> {
+					if (tries++ == 1)
+						throw new UnsupportedOperationException();
+					return param;
+				});
+			}
+		};
+		Launcher<MyServer> clientSideLauncher = DebugLauncher.createLauncher(client, MyServer.class, in, out);
+
+		// create server side
+		MyServer server = new MyServer() {
+			@Override
+			public CompletableFuture<MyParam> askServer(MyParam param) {
+				return CompletableFuture.completedFuture(param);
+			}
+		};
+		Launcher<MyClient> serverSideLauncher = DebugLauncher.createLauncher(server, MyClient.class, in2, out2);
+
+		clientSideLauncher.startListening();
+		serverSideLauncher.startListening();
+
+		CompletableFuture<MyParam> errorFuture1 = serverSideLauncher.getRemoteProxy().askClient(new MyParam("FOO"));
+		try {
+			System.out.println(errorFuture1.get());
+			Assert.fail();
+		} catch (ExecutionException e) {
+			Assert.assertNotNull(((ResponseErrorException)e.getCause()).getResponseError().getMessage());
+		}
+		CompletableFuture<MyParam> errorFuture2 = serverSideLauncher.getRemoteProxy().askClient(new MyParam("FOO"));
+		try {
+			errorFuture2.get();
+			Assert.fail();
+		} catch (ExecutionException e) {
+			Assert.assertNotNull(((ResponseErrorException)e.getCause()).getResponseError().getMessage());
+		}
+		CompletableFuture<MyParam> goodFuture = serverSideLauncher.getRemoteProxy().askClient(new MyParam("FOO"));
+		Assert.assertEquals("FOO", goodFuture.get(TIMEOUT, TimeUnit.MILLISECONDS).value);
+	}
+
+	@Test
+	public void testUnknownMessages() throws Exception {
+		// intercept log messages
+		LogMessageAccumulator logMessages = new LogMessageAccumulator();
+		try {
+			logMessages.registerTo(GenericEndpoint.class.getName());
+
+			// create client messages
+			String clientMessage1 = "{\"type\":\"event\","
+					+ "\"event\":\"foo1\",\n"
+					+ " \"body\":\"bar\"\n"
+					+ "}";
+			String clientMessage2 = "{\"type\":\"request\","
+					+ "\"seq\":1,\n"
+					+ "\"command\":\"foo2\",\n"
+					+ " \"arguments\":\"bar\"\n"
+					+ "}";
+			String clientMessages = getHeader(clientMessage1.getBytes().length) + clientMessage1
+					+ getHeader(clientMessage2.getBytes().length) + clientMessage2;
+
+			// create server side
+			ByteArrayInputStream in = new ByteArrayInputStream(clientMessages.getBytes());
+			ByteArrayOutputStream out = new ByteArrayOutputStream();
+			MyServer server = new MyServer() {
+				@Override
+				public CompletableFuture<MyParam> askServer(MyParam param) {
+					return CompletableFuture.completedFuture(param);
+				}
+			};
+			Launcher<MyClient> serverSideLauncher = DebugLauncher.createLauncher(server, MyClient.class, in, out);
+			serverSideLauncher.startListening().get(TIMEOUT, TimeUnit.MILLISECONDS);
+
+			logMessages.await(Level.WARNING, "Unsupported notification method: foo1");
+			logMessages.await(Level.WARNING, "Unsupported request method: foo2");
+
+			Assert.assertEquals("Content-Length: 121\r\n\r\n" +
+					"{\"type\":\"response\",\"seq\":1,\"request_seq\":1,\"command\":\"foo2\",\"success\":false,\"message\":\"Unsupported request method: foo2\"}",
+					out.toString());
+		} finally {
+			logMessages.unregister();
+		}
+	}
+
+	@Test
+	public void testUnknownOptionalMessages() throws Exception {
+		// intercept log messages
+		LogMessageAccumulator logMessages = new LogMessageAccumulator();
+		try {
+			logMessages.registerTo(GenericEndpoint.class.getName());
+
+			// create client messages
+			String clientMessage1 = "{\"type\":\"event\","
+					+ "\"event\":\"$/foo1\",\n"
+					+ " \"body\":\"bar\"\n"
+					+ "}";
+			String clientMessage2 = "{\"type\":\"request\","
+					+ "\"seq\":1,\n"
+					+ "\"command\":\"$/foo2\",\n"
+					+ " \"arguments\":\"bar\"\n"
+					+ "}";
+			String clientMessages = getHeader(clientMessage1.getBytes().length) + clientMessage1
+					+ getHeader(clientMessage2.getBytes().length) + clientMessage2;
+
+			// create server side
+			ByteArrayInputStream in = new ByteArrayInputStream(clientMessages.getBytes());
+			ByteArrayOutputStream out = new ByteArrayOutputStream();
+			MyServer server = new MyServer() {
+				@Override
+				public CompletableFuture<MyParam> askServer(MyParam param) {
+					return CompletableFuture.completedFuture(param);
+				}
+			};
+			Launcher<MyClient> serverSideLauncher = DebugLauncher.createLauncher(server, MyClient.class, in, out);
+			serverSideLauncher.startListening().get(TIMEOUT, TimeUnit.MILLISECONDS);
+
+			logMessages.await(Level.INFO, "Unsupported notification method: $/foo1");
+			logMessages.await(Level.INFO, "Unsupported request method: $/foo2");
+
+			Assert.assertEquals("Content-Length: 77\r\n\r\n" +
+					"{\"type\":\"response\",\"seq\":1,\"request_seq\":1,\"command\":\"$/foo2\",\"success\":true}",
+					out.toString());
+		} finally {
+			logMessages.unregister();
+		}
+	}
+
+	@Test
+	public void testResponse() throws Exception {
+		String clientMessage = "{\"type\":\"request\","
+				+ "\"seq\":1,\n"
+				+ "\"command\":\"askServer\",\n"
+				+ " \"arguments\": { value: \"bar\" }\n"
+				+ "}";
+		String clientMessages = getHeader(clientMessage.getBytes().length) + clientMessage;
+
+		// create server side
+		ByteArrayInputStream in = new ByteArrayInputStream(clientMessages.getBytes());
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		MyServer server = new MyServer() {
+			@Override
+			public CompletableFuture<MyParam> askServer(MyParam param) {
+				return CompletableFuture.completedFuture(param);
+			}
+		};
+		Launcher<MyClient> serverSideLauncher = DebugLauncher.createLauncher(server, MyClient.class, in, out);
+		serverSideLauncher.startListening().get(TIMEOUT, TimeUnit.MILLISECONDS);
+
+		Assert.assertEquals("Content-Length: 103\r\n\r\n" +
+				"{\"type\":\"response\",\"seq\":1,\"request_seq\":1,\"command\":\"askServer\",\"success\":true,\"body\":{\"value\":\"bar\"}}",
+				out.toString());
+	}
+
+	public static interface UnexpectedParamsTestServer {
+		@JsonNotification
+		void myNotification();
+	}
+
+	@Test
+	public void testUnexpectedParams() throws Exception {
+		// intercept log messages
+		LogMessageAccumulator logMessages = new LogMessageAccumulator();
+		try {
+			logMessages.registerTo(GenericEndpoint.class.getName());
+
+			// create client messages
+			String notificationMessage = "{\"type\":\"event\","
+					+ "\"event\":\"myNotification\",\n"
+					+ "\"body\": { \"value\": \"foo\" }\n"
+					+ "}";
+			String clientMessages = getHeader(notificationMessage.getBytes().length) + notificationMessage;
+
+			// create server side
+			ByteArrayInputStream in = new ByteArrayInputStream(clientMessages.getBytes());
+			ByteArrayOutputStream out = new ByteArrayOutputStream();
+			UnexpectedParamsTestServer server = new UnexpectedParamsTestServer() {
+				public void myNotification() {
+				}
+			};
+			Launcher<MyClient> serverSideLauncher = DebugLauncher.createLauncher(server, MyClient.class, in, out);
+			serverSideLauncher.startListening();
+
+			logMessages.await(Level.WARNING, "Unexpected params '{\"value\":\"foo\"}' for " + "'public abstract void "
+					+ UnexpectedParamsTestServer.class.getName() + ".myNotification()' is ignored");
+		} finally {
+			logMessages.unregister();
+		}
+	}
+
+    protected String getHeader(int contentLength) {
+        StringBuilder headerBuilder = new StringBuilder();
+        headerBuilder.append(CONTENT_LENGTH_HEADER).append(": ").append(contentLength).append(CRLF);
+        headerBuilder.append(CRLF);
+        return headerBuilder.toString();
+    }
+
+    /**
+     * Test a fully connected design with the {@link ReflectiveMessageValidator} enabled.
+     */
+	@Test
+	public void testValidatedRequests() throws Exception {
+		// create client side
+		PipedInputStream in = new PipedInputStream();
+		PipedOutputStream out = new PipedOutputStream();
+		PipedInputStream in2 = new PipedInputStream();
+		PipedOutputStream out2 = new PipedOutputStream();
+
+		in.connect(out2);
+		out.connect(in2);
+
+		MyClient client = new MyClient() {
+			@Override
+			public CompletableFuture<MyParam> askClient(MyParam param) {
+				return CompletableFuture.completedFuture(param);
+			}
+		};
+		Launcher<MyServer> clientSideLauncher = DebugLauncher.createLauncher(client, MyServer.class, in, out, true, null);
+
+		// create server side
+		MyServer server = new MyServer() {
+			@Override
+			public CompletableFuture<MyParam> askServer(MyParam param) {
+				return CompletableFuture.completedFuture(param);
+			}
+		};
+		Launcher<MyClient> serverSideLauncher = DebugLauncher.createLauncher(server, MyClient.class, in2, out2, true, null);
+
+		clientSideLauncher.startListening();
+		serverSideLauncher.startListening();
+
+		CompletableFuture<MyParam> fooFuture = clientSideLauncher.getRemoteProxy().askServer(new MyParam("FOO"));
+		CompletableFuture<MyParam> barFuture = serverSideLauncher.getRemoteProxy().askClient(new MyParam("BAR"));
+
+		Assert.assertEquals("FOO", fooFuture.get(TIMEOUT, TimeUnit.MILLISECONDS).value);
+		Assert.assertEquals("BAR", barFuture.get(TIMEOUT, TimeUnit.MILLISECONDS).value);
+	}
+
+
+}
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/debug/test/DebugLauncherTest.java b/javatests/org/eclipse/lsp4j/jsonrpc/debug/test/DebugLauncherTest.java
new file mode 100644
index 0000000..73aa13e
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/debug/test/DebugLauncherTest.java
@@ -0,0 +1,116 @@
+/******************************************************************************
+ * Copyright (c) 2016-2017 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.debug.test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.lsp4j.jsonrpc.Launcher;
+import org.eclipse.lsp4j.jsonrpc.debug.DebugLauncher;
+import org.eclipse.lsp4j.jsonrpc.services.JsonNotification;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+
+public class DebugLauncherTest {
+
+	private static final long TIMEOUT = 2000;
+
+	static class Param {
+		Param() {
+		}
+		Param(String message) {
+			this.message = message;
+		}
+		public String message;
+	}
+
+	static interface A {
+		@JsonNotification public void say(Param p);
+	}
+
+	@Test public void testDone() throws Exception {
+		A a = new A() {
+			@Override
+			public void say(Param p) {
+			}
+		};
+		Launcher<A> launcher = DebugLauncher.createLauncher(a, A.class, new ByteArrayInputStream("".getBytes()), new ByteArrayOutputStream());
+		Future<?> startListening = launcher.startListening();
+		startListening.get(TIMEOUT, TimeUnit.MILLISECONDS);
+		Assert.assertTrue(startListening.isDone());
+		Assert.assertFalse(startListening.isCancelled());
+	}
+
+	@Test public void testCanceled() throws Exception {
+		A a = new A() {
+			@Override
+			public void say(Param p) {
+			}
+		};
+		Launcher<A> launcher = DebugLauncher.createLauncher(a, A.class, new InputStream() {
+			@Override
+			public int read() throws IOException {
+				try {
+					Thread.sleep(100);
+				} catch (InterruptedException e) {
+					throw new RuntimeException(e);
+				}
+				return '\n';
+			}
+		}, new ByteArrayOutputStream());
+		Future<?> startListening = launcher.startListening();
+		startListening.cancel(true);
+		Assert.assertTrue(startListening.isDone());
+		Assert.assertTrue(startListening.isCancelled());
+	}
+
+	@Test public void testCustomGson() throws Exception {
+		A a = new A() {
+			@Override
+			public void say(Param p) {
+			}
+		};
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		TypeAdapter<Param> typeAdapter = new TypeAdapter<Param>() {
+			@Override
+			public void write(JsonWriter out, Param value) throws IOException {
+				out.beginObject();
+				out.name("message");
+				out.value("bar");
+				out.endObject();
+			}
+			@Override
+			public Param read(JsonReader in) throws IOException {
+				return null;
+			}
+		};
+		Launcher<A> launcher = DebugLauncher.createIoLauncher(a, A.class, new ByteArrayInputStream("".getBytes()), out,
+				Executors.newCachedThreadPool(), c -> c,
+				gsonBuilder -> {gsonBuilder.registerTypeAdapter(Param.class, typeAdapter);});
+		A remoteProxy = launcher.getRemoteProxy();
+
+		remoteProxy.say(new Param("foo"));
+		Assert.assertEquals("Content-Length: 63\r\n\r\n" +
+				"{\"type\":\"event\",\"seq\":1,\"event\":\"say\",\"body\":{\"message\":\"bar\"}}",
+				out.toString());
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/debug/test/DebugRemoteEndpointTest.java b/javatests/org/eclipse/lsp4j/jsonrpc/debug/test/DebugRemoteEndpointTest.java
new file mode 100644
index 0000000..d0b7a9d
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/debug/test/DebugRemoteEndpointTest.java
@@ -0,0 +1,130 @@
+/******************************************************************************
+ * Copyright (c) 2016-2017 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.debug.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.CompletableFuture;
+
+import org.eclipse.lsp4j.jsonrpc.Endpoint;
+import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
+import org.eclipse.lsp4j.jsonrpc.RemoteEndpoint;
+import org.eclipse.lsp4j.jsonrpc.debug.DebugRemoteEndpoint;
+import org.eclipse.lsp4j.jsonrpc.messages.Message;
+import org.eclipse.lsp4j.jsonrpc.messages.NotificationMessage;
+import org.eclipse.lsp4j.jsonrpc.messages.RequestMessage;
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseError;
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseErrorCode;
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage;
+import org.junit.Test;
+
+public class DebugRemoteEndpointTest {
+
+	static class TestEndpoint implements Endpoint {
+
+		List<NotificationMessage> notifications = new ArrayList<>();
+		Map<RequestMessage, CompletableFuture<Object>> requests = new LinkedHashMap<>();
+
+		public void notify(String method, Object parameter) {
+			notifications.add(new NotificationMessage() {{
+				setMethod(method);
+				setParams(parameter);
+			}});
+		}
+
+		@Override
+		public CompletableFuture<Object> request(String method, Object parameter) {
+			CompletableFuture<Object> completableFuture = new CompletableFuture<Object>();
+			requests.put(new RequestMessage() {{
+				setMethod(method);
+				setParams(parameter);
+			}}, completableFuture);
+			return completableFuture;
+		}
+
+	}
+
+	static class TestMessageConsumer implements MessageConsumer {
+
+		List<Message> messages = new ArrayList<>();
+
+		@Override
+		public void consume(Message message) {
+			messages.add(message);
+		}
+
+	}
+
+	@Test public void testNotification() {
+		TestEndpoint endp = new TestEndpoint();
+		TestMessageConsumer consumer = new TestMessageConsumer();
+		RemoteEndpoint endpoint = new DebugRemoteEndpoint(consumer, endp);
+
+		endpoint.consume(new NotificationMessage() {{
+			setMethod("foo");
+			setParams("myparam");
+		}});
+
+		NotificationMessage notificationMessage = endp.notifications.get(0);
+		assertEquals("foo", notificationMessage.getMethod());
+		assertEquals("myparam", notificationMessage.getParams());
+		assertTrue(consumer.messages.isEmpty());
+	}
+
+	@Test public void testRequest() {
+		TestEndpoint endp = new TestEndpoint();
+		TestMessageConsumer consumer = new TestMessageConsumer();
+		RemoteEndpoint endpoint = new DebugRemoteEndpoint(consumer, endp);
+
+		endpoint.consume(new RequestMessage() {{
+			setId("1");
+			setMethod("foo");
+			setParams("myparam");
+		}});
+
+		Entry<RequestMessage, CompletableFuture<Object>> entry = endp.requests.entrySet().iterator().next();
+		entry.getValue().complete("success");
+		assertEquals("foo", entry.getKey().getMethod());
+		assertEquals("myparam", entry.getKey().getParams());
+		assertEquals("success", ((ResponseMessage)consumer.messages.get(0)).getResult());
+	}
+
+	@Test public void testCancellation() {
+		TestEndpoint endp = new TestEndpoint();
+		TestMessageConsumer consumer = new TestMessageConsumer();
+		RemoteEndpoint endpoint = new DebugRemoteEndpoint(consumer, endp);
+
+		endpoint.consume(new RequestMessage() {{
+			setId("1");
+			setMethod("foo");
+			setParams("myparam");
+		}});
+
+		Entry<RequestMessage, CompletableFuture<Object>> entry = endp.requests.entrySet().iterator().next();
+		entry.getValue().cancel(true);
+		ResponseMessage message = (ResponseMessage) consumer.messages.get(0);
+		assertNotNull(message);
+		ResponseError error = message.getError();
+		assertNotNull(error);
+		assertEquals(error.getCode(), ResponseErrorCode.RequestCancelled.getValue());
+		assertEquals(error.getMessage(), "The request (id: 1, method: 'foo') has been cancelled");
+
+	}
+
+}
\ No newline at end of file
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/debug/test/LogMessageAccumulator.java b/javatests/org/eclipse/lsp4j/jsonrpc/debug/test/LogMessageAccumulator.java
new file mode 100644
index 0000000..908eff5
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/debug/test/LogMessageAccumulator.java
@@ -0,0 +1,111 @@
+/******************************************************************************
+ * Copyright (c) 2016-2017 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.debug.test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Predicate;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import org.junit.Assert;
+
+public class LogMessageAccumulator extends Handler {
+
+	private static final long TIMEOUT = 2000;
+
+	private final List<LogRecord> records = new ArrayList<>();
+	private final List<Logger> registeredLoggers = new ArrayList<>();
+	
+	public Logger registerTo(Class<?> clazz) {
+		return registerTo(clazz.getName());
+	}
+	
+	public Logger registerTo(String name) {
+		Logger logger = Logger.getLogger(name);
+		logger.setUseParentHandlers(false);
+		logger.addHandler(this);
+		logger.setLevel(Level.ALL);
+		registeredLoggers.add(logger);
+		return logger;
+	}
+	
+	public void unregister() {
+		for (Logger logger : registeredLoggers) {
+			logger.setLevel(null);
+			logger.removeHandler(this);
+			logger.setUseParentHandlers(true);
+		}
+		registeredLoggers.clear();
+	}
+
+	public List<LogRecord> getRecords() {
+		return records;
+	}
+
+	public LogRecord findRecord(Level level, String message) {
+		synchronized (records) {
+			for (LogRecord r : records) {
+				if (level.equals(r.getLevel()) && message.equals(r.getMessage()))
+					return r;
+			}
+			return null;
+		}
+	}
+
+	public Optional<LogRecord> match(Predicate<LogRecord> predicate) {
+		synchronized (records) {
+			return records.stream().filter(predicate).findFirst();
+		}
+	}
+
+	@Override
+	public void publish(LogRecord record) {
+		synchronized (records) {
+			records.add(record);
+		}
+	}
+
+	@Override
+	public void flush() {
+	}
+
+	@Override
+	public void close() throws SecurityException {
+	}
+
+	public void await(Predicate<LogRecord> predicate) throws InterruptedException {
+		long startTime = System.currentTimeMillis();
+		while (!match(predicate).isPresent()) {
+			Thread.sleep(20);
+			if (System.currentTimeMillis() - startTime > TIMEOUT) {
+				synchronized (records) {
+					String records = this.records.stream().map(r -> r.getLevel() + ": " + r.getMessage()).reduce((a, a2) -> a + '\n' + a2).get();
+					Assert.fail("Timeout elapsed while waiting for logging, logged:\n" + records);
+				}
+			}
+		}
+	}
+
+	public void await(Level level, String message) throws InterruptedException {
+		long startTime = System.currentTimeMillis();
+		while (findRecord(level, message) == null) {
+			Thread.sleep(20);
+			if (System.currentTimeMillis() - startTime > TIMEOUT)
+				Assert.fail("Timeout elapsed while waiting for " + level + ": " + message);
+		}
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/debug/test/json/DebugMessageJsonHandlerTest.java b/javatests/org/eclipse/lsp4j/jsonrpc/debug/test/json/DebugMessageJsonHandlerTest.java
new file mode 100644
index 0000000..3891176
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/debug/test/json/DebugMessageJsonHandlerTest.java
@@ -0,0 +1,851 @@
+/******************************************************************************
+ * Copyright (c) 2016-2017 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.debug.test.json;
+
+import static org.junit.Assert.fail;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Consumer;
+
+import org.eclipse.lsp4j.jsonrpc.MessageIssueException;
+import org.eclipse.lsp4j.jsonrpc.debug.json.DebugMessageJsonHandler;
+import org.eclipse.lsp4j.jsonrpc.debug.messages.DebugRequestMessage;
+import org.eclipse.lsp4j.jsonrpc.json.JsonRpcMethod;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.messages.Message;
+import org.eclipse.lsp4j.jsonrpc.messages.MessageIssue;
+import org.eclipse.lsp4j.jsonrpc.messages.NotificationMessage;
+import org.eclipse.lsp4j.jsonrpc.messages.RequestMessage;
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.google.gson.reflect.TypeToken;
+
+public class DebugMessageJsonHandlerTest {
+
+	public static class Entry {
+		public String name;
+		public int kind;
+		public Location location;
+	}
+
+	public static class Location {
+		public String uri;
+	}
+
+	@SuppressWarnings({ "unchecked" })
+	@Test
+	public void testParseList() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<List<? extends Entry>>() {}.getType(),
+				new TypeToken<List<? extends Entry>>() {}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id)->"foo");
+		Message message = handler.parseMessage("{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"response\",\n"
+				+ "\"success\":true,\n"
+				+ " \"body\": [\n"
+				+ "  {\"name\":\"$schema\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":1,\"character\":3},\"end\":{\"line\":1,\"character\":55}}}},\n"
+				+ "  {\"name\":\"type\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":2,\"character\":3},\"end\":{\"line\":2,\"character\":19}}}},\n"
+				+ "  {\"name\":\"title\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":3,\"character\":3},\"end\":{\"line\":3,\"character\":50}}}},\n"
+				+ "  {\"name\":\"additionalProperties\",\"kind\":17,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":4,\"character\":4},\"end\":{\"line\":4,\"character\":32}}}},\n"
+				+ "  {\"name\":\"properties\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":5,\"character\":3},\"end\":{\"line\":5,\"character\":20}}}}\n"
+				+ "]}");
+		List<? extends Entry> result = (List<? extends Entry>) ((ResponseMessage)message).getResult();
+		Assert.assertEquals(5, result.size());
+		for (Entry e : result) {
+			Assert.assertTrue(e.location.uri, e.location.uri.startsWith("file:/home/mistria"));
+		}
+	}
+
+	@SuppressWarnings({ "unchecked" })
+	@Test
+	public void testParseList_02() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Set<Entry>>() {}.getType(),
+				new TypeToken<Set<Entry>>() {}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id)->"foo");
+		Message message = handler.parseMessage("{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"response\",\n"
+				+ "\"success\":true,\n"
+				+ " \"body\": [\n"
+				+ "  {\"name\":\"$schema\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":1,\"character\":3},\"end\":{\"line\":1,\"character\":55}}}},\n"
+				+ "  {\"name\":\"type\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":2,\"character\":3},\"end\":{\"line\":2,\"character\":19}}}},\n"
+				+ "  {\"name\":\"title\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":3,\"character\":3},\"end\":{\"line\":3,\"character\":50}}}},\n"
+				+ "  {\"name\":\"additionalProperties\",\"kind\":17,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":4,\"character\":4},\"end\":{\"line\":4,\"character\":32}}}},\n"
+				+ "  {\"name\":\"properties\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":5,\"character\":3},\"end\":{\"line\":5,\"character\":20}}}}\n"
+				+ "]}");
+		Set<Entry> result = (Set<Entry>) ((ResponseMessage)message).getResult();
+		Assert.assertEquals(5, result.size());
+		for (Entry e : result) {
+			Assert.assertTrue(e.location.uri, e.location.uri.startsWith("file:/home/mistria"));
+		}
+	}
+
+	@SuppressWarnings({ "unchecked" })
+	@Test
+	public void testEither_01() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Either<String, List<Map<String,String>>>>() {}.getType(),
+				new TypeToken<Either<String, Integer>>() {}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		Message message = handler.parseMessage("{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"response\",\n"
+				+ "\"success\":true,\n"
+				+ " \"body\": [\n"
+				+ "  {\"name\":\"foo\"},\n"
+				+ "  {\"name\":\"bar\"}\n"
+				+ "]}");
+		Either<String, List<Map<String, String>>> result = (Either<String, List<Map<String,String>>>) ((ResponseMessage)message).getResult();
+		Assert.assertTrue(result.isRight());
+		for (Map<String, String> e : result.getRight()) {
+			Assert.assertNotNull(e.get("name"));
+		}
+		message = handler.parseMessage("{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"response\",\n"
+				+ "\"success\":true,\n"
+				+ "\"body\": \"name\"\n"
+				+ "}");
+		result = (Either<String, List<Map<String,String>>>) ((ResponseMessage)message).getResult();
+		Assert.assertFalse(result.isRight());
+		Assert.assertEquals("name",result.getLeft());
+	}
+
+	@SuppressWarnings({ "unchecked" })
+	@Test
+	public void testEither_02() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Either<Integer, Map<String,String>>>() {}.getType(),
+				new TypeToken<Object>() {}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		Message message = handler.parseMessage("{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"response\",\n"
+				+ "\"success\":true,\n"
+				+ "\"body\": 2\n"
+				+ "}");
+		Either<Integer, List<Map<String, String>>> result = (Either<Integer, List<Map<String,String>>>) ((ResponseMessage)message).getResult();
+		Assert.assertTrue(result.isLeft());
+		Assert.assertEquals(Integer.valueOf(2), result.getLeft());
+	}
+
+	@SuppressWarnings({ "unchecked" })
+	@Test
+	public void testEither_03() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Either<Either<Integer, Map<String,String>>, List<Either<Integer, Map<String,String>>>>>() {}.getType(),
+				new TypeToken<Object>() {}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+
+		Message message = handler.parseMessage("{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"response\",\n"
+				+ "\"success\":true,\n"
+				+ "\"body\": 2\n"
+				+ "}");
+		Either<Either<Integer, Map<String,String>>, List<Either<Integer, Map<String,String>>>> result = (Either<Either<Integer, Map<String, String>>, List<Either<Integer, Map<String, String>>>>) ((ResponseMessage)message).getResult();
+		Assert.assertTrue(result.isLeft());
+		Assert.assertTrue(result.getLeft().isLeft());
+		Assert.assertEquals(Integer.valueOf(2), result.getLeft().getLeft());
+
+		message = handler.parseMessage("{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"response\",\n"
+				+ "\"success\":true,\n"
+				+ " \"body\": {\n"
+				+ "  \"foo\":\"1\",\n"
+				+ "  \"bar\":\"2\"\n"
+				+ "}}");
+		result = (Either<Either<Integer, Map<String, String>>, List<Either<Integer, Map<String, String>>>>) ((ResponseMessage)message).getResult();
+		Assert.assertTrue(result.isLeft());
+		Assert.assertTrue(result.getLeft().isRight());
+		Assert.assertEquals("1", result.getLeft().getRight().get("foo"));
+		Assert.assertEquals("2", result.getLeft().getRight().get("bar"));
+
+		message = handler.parseMessage("{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"response\",\n"
+				+ "\"success\":true,\n"
+				+ " \"body\": [{\n"
+				+ "  \"foo\":\"1\",\n"
+				+ "  \"bar\":\"2\"\n"
+				+ "}]}");
+		result = (Either<Either<Integer, Map<String, String>>, List<Either<Integer, Map<String, String>>>>) ((ResponseMessage)message).getResult();
+		Assert.assertTrue(result.isRight());
+		Assert.assertTrue(result.getRight().get(0).isRight());
+		Assert.assertEquals("1", result.getRight().get(0).getRight().get("foo"));
+		Assert.assertEquals("2", result.getRight().get(0).getRight().get("bar"));
+
+		message = handler.parseMessage("{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"response\",\n"
+				+ "\"success\":true,\n"
+				+ " \"body\": [\n"
+				+ "  2\n"
+				+ "]}");
+		result = (Either<Either<Integer, Map<String, String>>, List<Either<Integer, Map<String, String>>>>) ((ResponseMessage)message).getResult();
+		Assert.assertTrue(result.isRight());
+		Assert.assertTrue(result.getRight().get(0).isLeft());
+		Assert.assertEquals(Integer.valueOf(2), result.getRight().get(0).getLeft());
+	}
+
+	@SuppressWarnings({ "unchecked" })
+	@Test
+	public void testEither_04() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Either<MyClass, List<? extends MyClass>>>() {}.getType(),
+				new TypeToken<Object>() {}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+
+		Message message = handler.parseMessage("{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"response\",\n"
+				+ "\"success\":true,\n"
+				+ "\"body\": {\n"
+				+ "  value:\"foo\"\n"
+				+ "}}");
+		Either<MyClass, List<? extends MyClass>> result = (Either<MyClass, List<? extends MyClass>>) ((ResponseMessage)message).getResult();
+		Assert.assertTrue(result.isLeft());
+		Assert.assertEquals("foo", result.getLeft().getValue());
+
+		message = handler.parseMessage("{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"response\",\n"
+				+ "\"success\":true,\n"
+				+ "\"body\": [{\n"
+				+ "  value:\"bar\"\n"
+				+ "}]}");
+		result = (Either<MyClass, List<? extends MyClass>>) ((ResponseMessage)message).getResult();
+		Assert.assertTrue(result.isRight());
+		Assert.assertEquals("bar", result.getRight().get(0).getValue());
+	}
+
+	@SuppressWarnings({ "unchecked" })
+	@Test
+	public void testEither_05() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Either<List<MyClass>, MyClassList>>() {}.getType(),
+				new TypeToken<Object>() {}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+
+		Message message = handler.parseMessage("{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"response\",\n"
+				+ "\"success\":true,\n"
+				+ "\"body\": [{\n"
+				+ "  value:\"foo\"\n"
+				+ "}]}");
+		Either<List<MyClass>, MyClassList> result = (Either<List<MyClass>, MyClassList>) ((ResponseMessage)message).getResult();
+		Assert.assertTrue(result.isLeft());
+		Assert.assertEquals("foo", result.getLeft().get(0).getValue());
+
+		message = handler.parseMessage("{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"response\",\n"
+				+ "\"success\":true,\n"
+				+ "\"body\": {\n"
+				+ "  items: [{\n"
+				+ "    value:\"bar\"\n"
+				+ "}]}}");
+		result = (Either<List<MyClass>, MyClassList>) ((ResponseMessage)message).getResult();
+		Assert.assertTrue(result.isRight());
+		Assert.assertEquals("bar", result.getRight().getItems().get(0).getValue());
+	}
+
+	@Test
+	public void testParamsParsing_01() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<Location>() {}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		RequestMessage message = (RequestMessage) handler.parseMessage("{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"request\",\n"
+				+ "\"arguments\": {\"uri\": \"dummy://mymodel.mydsl\"},\n"
+				+ "\"command\":\"foo\"\n"
+				+ "}");
+		Object params = message.getParams();
+		Class<? extends Object> class1 = params.getClass();
+		Assert.assertEquals(Location.class, class1);
+	}
+
+	@Test
+	public void testParamsParsing_02() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<Location>() {}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+
+		RequestMessage message = (RequestMessage) handler.parseMessage("{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"request\",\n"
+				+ "\"command\":\"foo\",\n"
+				+ "\"arguments\": {\"uri\": \"dummy://mymodel.mydsl\"}\n"
+				+ "}");
+		Assert.assertEquals(Location.class, message.getParams().getClass());
+	}
+
+	@Test
+	public void testParamsParsing_03() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<Location>() {}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+
+		RequestMessage message = (RequestMessage) handler.parseMessage("{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"request\",\n"
+				+ "\"command\":\"bar\",\n"
+				+ "\"arguments\": {\"uri\": \"dummy://mymodel.mydsl\"}\n"
+				+ "}");
+		Assert.assertEquals(JsonObject.class, message.getParams().getClass());
+	}
+
+	@Test
+	public void testParamsParsing_04() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<Location>() {}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+
+		RequestMessage message = (RequestMessage) handler.parseMessage("{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"request\",\n"
+				+ "\"command\":\"bar\",\n"
+				+ "\"arguments\": null\n"
+				+ "}");
+		Assert.assertEquals(null, message.getParams());
+	}
+
+	@Test
+	public void testRawMultiParamsParsing_01() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<String>() {}.getType(),
+				new TypeToken<Integer>() {}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+
+		RequestMessage message = (RequestMessage) handler.parseMessage("{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"request\",\n"
+				+ "\"command\":\"foo\",\n"
+				+ "\"arguments\": [\"foo\", 2]\n"
+				+ "}");
+		Assert.assertTrue("" + message.getParams().getClass(), message.getParams() instanceof List);
+
+		List<?> parameters = (List<?>) message.getParams();
+		Assert.assertEquals(2, parameters.size());
+		Assert.assertEquals("foo", parameters.get(0));
+		Assert.assertEquals(2, parameters.get(1));
+	}
+
+	@Test
+	public void testRawMultiParamsParsing_02() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<String>() {}.getType(),
+				new TypeToken<Integer>() {}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+
+		RequestMessage message = (RequestMessage) handler.parseMessage("{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"request\",\n"
+				+ "\"command\":\"bar\",\n"
+				+ "\"arguments\": [\"foo\", 2]\n"
+				+ "}");
+		Assert.assertTrue("" + message.getParams().getClass(), message.getParams() instanceof JsonArray);
+	}
+
+	@Test
+	public void testRawMultiParamsParsing_03() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<List<String>>() {}.getType(),
+				new TypeToken<List<Integer>>() {}.getType(),
+				new TypeToken<Location>() {}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+
+		RequestMessage message = (RequestMessage) handler.parseMessage("{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"request\",\n"
+				+ "\"command\":\"foo\",\n"
+				+ "\"arguments\": [[\"foo\", \"bar\"], [1, 2], {\"uri\": \"dummy://mymodel.mydsl\"}]\n"
+				+ "}");
+		Assert.assertTrue("" + message.getParams().getClass(), message.getParams() instanceof List);
+
+		List<?> parameters = (List<?>) message.getParams();
+		Assert.assertEquals(3, parameters.size());
+		Assert.assertEquals("[foo, bar]", parameters.get(0).toString());
+		Assert.assertEquals("[1, 2]", parameters.get(1).toString());
+		Assert.assertTrue("" + parameters.get(2).getClass(), parameters.get(2) instanceof Location);
+	}
+
+	@Test
+	public void testRawMultiParamsParsing_04() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<List<String>>() {}.getType(),
+				new TypeToken<List<Integer>>() {}.getType(),
+				new TypeToken<Location>() {}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+
+		RequestMessage message = (RequestMessage) handler.parseMessage("{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"request\",\n"
+				+ "\"command\":\"foo\",\n"
+				+ "\"arguments\": [[\"foo\", \"bar\"], [1, 2]]\n"
+				+ "}");
+		Assert.assertTrue("" + message.getParams().getClass(), message.getParams() instanceof List);
+
+		List<?> parameters = (List<?>) message.getParams();
+		Assert.assertEquals(3, parameters.size());
+		Assert.assertEquals("[foo, bar]", parameters.get(0).toString());
+		Assert.assertEquals("[1, 2]", parameters.get(1).toString());
+		Assert.assertNull(parameters.get(2));
+	}
+
+	@Test
+	public void testMultiParamsParsing_01() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<String>() {}.getType(),
+				new TypeToken<Integer>() {}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+
+		RequestMessage message = (RequestMessage) handler.parseMessage("{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"request\",\n"
+				+ "\"arguments\": [\"foo\", 2],\n"
+				+ "\"command\":\"foo\"\n"
+				+ "}");
+		Assert.assertTrue("" + message.getParams().getClass(), message.getParams() instanceof List);
+
+		List<?> parameters = (List<?>) message.getParams();
+		Assert.assertEquals(2, parameters.size());
+		Assert.assertEquals("foo", parameters.get(0));
+		Assert.assertEquals(2, parameters.get(1));
+	}
+
+	@Test
+	public void testMultiParamsParsing_02() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<String>() {}.getType(),
+				new TypeToken<Integer>() {}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+
+		RequestMessage message = (RequestMessage) handler.parseMessage("{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"request\",\n"
+				+ "\"arguments\": [\"foo\", 2],\n"
+				+ "\"command\":\"bar\"\n"
+				+ "}");
+		Assert.assertTrue("" + message.getParams().getClass(), message.getParams() instanceof JsonArray);
+	}
+
+	@Test
+	public void testMultiParamsParsing_03() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<List<String>>() {}.getType(),
+				new TypeToken<List<Integer>>() {}.getType(),
+				new TypeToken<Location>() {}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+
+		RequestMessage message = (RequestMessage) handler.parseMessage("{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"request\",\n"
+				+ "\"arguments\": [[\"foo\", \"bar\"], [1, 2], {\"uri\": \"dummy://mymodel.mydsl\"}],\n"
+				+ "\"command\":\"foo\"\n"
+				+ "}");
+		Assert.assertTrue("" + message.getParams().getClass(), message.getParams() instanceof List);
+
+		List<?> parameters = (List<?>) message.getParams();
+		Assert.assertEquals(3, parameters.size());
+		Assert.assertEquals("[foo, bar]", parameters.get(0).toString());
+		Assert.assertEquals("[1, 2]", parameters.get(1).toString());
+		Assert.assertTrue("" + parameters.get(2).getClass(), parameters.get(2) instanceof Location);
+	}
+
+	@Test
+	public void testMultiParamsParsing_04() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<List<String>>() {}.getType(),
+				new TypeToken<List<Integer>>() {}.getType(),
+				new TypeToken<Location>() {}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+
+		RequestMessage message = (RequestMessage) handler.parseMessage("{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"request\",\n"
+				+ "\"arguments\": [[\"foo\", \"bar\"], [1, 2]],\n"
+				+ "\"command\":\"foo\"\n"
+				+ "}");
+		Assert.assertTrue("" + message.getParams().getClass(), message.getParams() instanceof List);
+
+		List<?> parameters = (List<?>) message.getParams();
+		Assert.assertEquals(3, parameters.size());
+		Assert.assertEquals("[foo, bar]", parameters.get(0).toString());
+		Assert.assertEquals("[1, 2]", parameters.get(1).toString());
+		Assert.assertNull(parameters.get(2));
+	}
+
+	@Test
+	public void testEnumParam() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<List<MyDebugEnum>>() {}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		RequestMessage message = (RequestMessage) handler.parseMessage("{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"request\",\n"
+				+ "\"arguments\": [\"enum1\", \"anotherEnum\", \"aStrangeEnumUTC\"],\n"
+				+ "\"command\":\"foo\"\n"
+				+ "}");
+		Assert.assertTrue("" + message.getParams().getClass(), message.getParams() instanceof List);
+
+		List<?> parameters = (List<?>) message.getParams();
+		Assert.assertEquals(3, parameters.size());
+		Assert.assertEquals(Arrays.asList(MyDebugEnum.ENUM1, MyDebugEnum.ANOTHER_ENUM, MyDebugEnum.A_STRANGE_ENUM_UTC),
+				parameters);
+	}
+
+	public static final <T> void swap(T[] a, int i, int j) {
+		T t = a[i];
+		a[i] = a[j];
+		a[j] = t;
+	}
+
+	public <T> void testAllPermutationsInner(T[] array, int i, int n, Consumer<T[]> test) {
+		int j;
+		if (i == n) {
+			test.accept(array);
+		} else {
+			for (j = i; j <= n; j++) {
+				swap(array, i, j);
+				testAllPermutationsInner(array, i + 1, n, test);
+				swap(array, i, j);
+			}
+		}
+	}
+
+	public <T> void testAllPermutationsStart(T[] array, Consumer<T[]> test) {
+		testAllPermutationsInner(array, 0, array.length - 1, test);
+	}
+
+	public void testAllPermutations(String[] properties, Consumer<String> test) {
+		testAllPermutationsStart(properties, mutatedProperties -> {
+			StringBuilder json = new StringBuilder();
+			json.append("{");
+			for (int k = 0; k < mutatedProperties.length; k++) {
+				json.append(mutatedProperties[k]);
+				if (k != mutatedProperties.length - 1) {
+					json.append(",");
+				}
+
+			}
+			json.append("}");
+			String jsonString = json.toString();
+			try {
+				test.accept(jsonString);
+			} catch (Exception | AssertionError e) {
+				// To make it easier to debug a failing test, add another exception
+				// layer that shows the version of the json used -- you may
+				// need to turn off "Filter Stack Trace" in JUnit view in Eclipse
+				// to see the underlying error.
+				throw new AssertionError("Failed with this input json: " + jsonString, e);
+			}
+		});
+	}
+
+	@Test
+	public void testThePermutationsTest() {
+		// make sure that the testAllPermutations works as expected
+		Set<String> collectedPermutations = new HashSet<>();
+		Set<String> expectedPermutations = new HashSet<>();
+		expectedPermutations.add("{a,b,c}");
+		expectedPermutations.add("{a,c,b}");
+		expectedPermutations.add("{b,a,c}");
+		expectedPermutations.add("{b,c,a}");
+		expectedPermutations.add("{c,a,b}");
+		expectedPermutations.add("{c,b,a}");
+		testAllPermutations(new String[] {"a", "b", "c"}, perm -> collectedPermutations.add(perm));
+		Assert.assertEquals(expectedPermutations, collectedPermutations);
+	}
+
+	@Test
+	public void testRequest_AllOrders() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<Location>() {
+				}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		String[] properties = new String[] {
+				"\"seq\":2",
+				"\"type\":\"request\"",
+				"\"command\":\"foo\"",
+				"\"arguments\": {\"uri\": \"dummy://mymodel.mydsl\"}"
+				};
+		testAllPermutations(properties, json -> {
+			RequestMessage message = (RequestMessage) handler.parseMessage(json);
+			Object params = message.getParams();
+			Class<? extends Object> class1 = params.getClass();
+			Assert.assertEquals(Location.class, class1);
+			Assert.assertEquals("dummy://mymodel.mydsl", ((Location)params).uri);
+		});
+	}
+
+	@Test
+	public void testNormalResponse_AllOrders() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Location>() {}.getType(),
+				new TypeToken<Void>() {
+				}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		String[] properties = new String[] {
+				"\"seq\":2",
+				"\"type\":\"response\"",
+				"\"request_seq\":5",
+				"\"success\":true",
+				"\"body\": {\"uri\": \"dummy://mymodel.mydsl\"}"
+				};
+		testAllPermutations(properties, json -> {
+			ResponseMessage message = (ResponseMessage) handler.parseMessage(json);
+			Object result = message.getResult();
+			Class<? extends Object> class1 = result.getClass();
+			Assert.assertEquals(Location.class, class1);
+			Assert.assertEquals("dummy://mymodel.mydsl", ((Location)result).uri);
+			Assert.assertNull(message.getError());
+		});
+	}
+
+    @Test
+    public void testNormalResponseExtraFields_AllOrders() {
+        Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+        supportedMethods.put("foo", JsonRpcMethod.request("foo",
+                new TypeToken<Location>() {}.getType(),
+                new TypeToken<Void>() {
+                }.getType()));
+        DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+        handler.setMethodProvider((id) -> "foo");
+        String[] properties = new String[] {
+                "\"seq\":2",
+                "\"type\":\"response\"",
+                "\"request_seq\":5",
+                "\"success\":true",
+                "\"body\": {\"uri\": \"dummy://mymodel.mydsl\"}",
+                "\"message\": null"
+                };
+        testAllPermutations(properties, json -> {
+            ResponseMessage message = (ResponseMessage) handler.parseMessage(json);
+            Object result = message.getResult();
+            Class<? extends Object> class1 = result.getClass();
+            Assert.assertEquals(Location.class, class1);
+            Assert.assertEquals("dummy://mymodel.mydsl", ((Location)result).uri);
+            Assert.assertNull(message.getError());
+        });
+    }
+
+	@Test
+	public void testErrorResponse_AllOrders() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Location>() {}.getType(),
+				new TypeToken<Void>() {
+				}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		String[] properties = new String[] {
+				"\"seq\":2",
+				"\"type\":\"response\"",
+				"\"request_seq\":5",
+				"\"success\":false",
+				"\"message\": \"failed\"",
+				"\"body\": {\"uri\": \"failed\"}"
+				};
+		testAllPermutations(properties, json -> {
+			ResponseMessage message = (ResponseMessage) handler.parseMessage(json);
+			Assert.assertEquals("failed", message.getError().getMessage());
+			Object data = message.getError().getData();
+			Map<String, String> expected = new HashMap<>();
+			expected.put("uri", "failed");
+			Assert.assertEquals(expected, data);
+			Assert.assertNull(message.getResult());
+		});
+	}
+
+	@Test
+	public void testNotification_AllOrders() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<Location>() {
+				}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		String[] properties = new String[] {
+				"\"seq\":2",
+				"\"type\":\"event\"",
+				"\"event\":\"foo\"",
+				"\"body\": {\"uri\": \"dummy://mymodel.mydsl\"}"
+				};
+		testAllPermutations(properties, json -> {
+			NotificationMessage message = (NotificationMessage) handler.parseMessage(json);
+			Object params = message.getParams();
+			Class<? extends Object> class1 = params.getClass();
+			Assert.assertEquals(Location.class, class1);
+			Assert.assertEquals("dummy://mymodel.mydsl", ((Location)params).uri);
+		});
+	}
+
+	@Test
+	public void testMissingSuccessResponse_AllOrders() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Location>() {}.getType(),
+				new TypeToken<Void>() {
+				}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		String[] properties = new String[] {
+				"\"seq\":2",
+				"\"type\":\"response\"",
+				"\"request_seq\":5",
+				"\"message\": \"failed\"",
+				"\"body\": {\"uri\": \"failed\"}"
+				};
+		testAllPermutations(properties, json -> {
+			ResponseMessage message = (ResponseMessage) handler.parseMessage(json);
+			Assert.assertEquals("failed", message.getError().getMessage());
+			Object data = message.getError().getData();
+			Map<String, String> expected = new HashMap<>();
+			expected.put("uri", "failed");
+			Assert.assertEquals(expected, data);
+			Assert.assertNull(message.getResult());
+		});
+	}
+
+	@Test
+	public void testParseErrorRequest() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<Location>() {}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		String input = "{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"request\",\n"
+				+ "\"command\":\"foo\"\n"
+				+ "\"arguments\": \"ERROR HERE - a string where an object is expected\",\n"
+				+ "}";
+		try {
+			handler.parseMessage(input);
+			fail("Should have had a parse error");
+		} catch (MessageIssueException e) {
+			// Make sure the message parsed ok up until the parse error
+			DebugRequestMessage rpcMessage = (DebugRequestMessage)e.getRpcMessage();
+			Assert.assertEquals("2", rpcMessage.getId());
+			Assert.assertEquals("foo", rpcMessage.getMethod());
+
+			// check there is an underlying error
+			MessageIssue messageIssue = e.getIssues().get(0);
+			Assert.assertNotNull(messageIssue.getCause());
+		}
+	}
+
+	@Test
+	public void testParseSyntaxErrorRequest() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<Location>() {}.getType()));
+		DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		String input = "{"
+				+ "\"seq\":2,\n"
+				+ "\"type\":\"request\",\n"
+				+ "\"command\":\"foo\"\n"
+				+ "\"arguments\": \"ERROR HERE - an unterminated string,\n"
+				+ "}";
+		try {
+			handler.parseMessage(input);
+			fail("Should have had a parse error");
+		} catch (MessageIssueException e) {
+			// Make sure the message parsed ok up until the parse error
+			DebugRequestMessage rpcMessage = (DebugRequestMessage)e.getRpcMessage();
+			Assert.assertEquals("2", rpcMessage.getId());
+			Assert.assertEquals("foo", rpcMessage.getMethod());
+
+			// check there is an underlying error
+			MessageIssue messageIssue = e.getIssues().get(0);
+			Assert.assertNotNull(messageIssue.getCause());
+		}
+	}
+}
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/debug/test/json/MyClass.java b/javatests/org/eclipse/lsp4j/jsonrpc/debug/test/json/MyClass.java
new file mode 100644
index 0000000..73b85c0
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/debug/test/json/MyClass.java
@@ -0,0 +1,53 @@
+/******************************************************************************
+ * Copyright (c) 2016-2017 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.debug.test.json;
+
+public class MyClass {
+
+	private String value;
+
+	public String getValue() {
+		return value;
+	}
+
+	public void setValue(String value) {
+		this.value = value;
+	}
+
+	public String toString() {
+		return "MyClass [value=" + value + "]";
+	}
+
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((value == null) ? 0 : value.hashCode());
+		return result;
+	}
+
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MyClass other = (MyClass) obj;
+		if (value == null) {
+			if (other.value != null)
+				return false;
+		} else if (!value.equals(other.value))
+			return false;
+		return true;
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/debug/test/json/MyClassList.java b/javatests/org/eclipse/lsp4j/jsonrpc/debug/test/json/MyClassList.java
new file mode 100644
index 0000000..664b84f
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/debug/test/json/MyClassList.java
@@ -0,0 +1,56 @@
+/******************************************************************************
+ * Copyright (c) 2016-2017 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.debug.test.json;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MyClassList {
+
+	private List<MyClass> items = new ArrayList<>();
+
+	public List<MyClass> getItems() {
+		return items;
+	}
+
+	public void setItems(List<MyClass> items) {
+		this.items = items;
+	}
+
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((items == null) ? 0 : items.hashCode());
+		return result;
+	}
+
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MyClassList other = (MyClassList) obj;
+		if (items == null) {
+			if (other.items != null)
+				return false;
+		} else if (!items.equals(other.items))
+			return false;
+		return true;
+	}
+
+	public String toString() {
+		return "MyClassList [items=" + items + "]";
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/debug/test/json/MyDebugEnum.java b/javatests/org/eclipse/lsp4j/jsonrpc/debug/test/json/MyDebugEnum.java
new file mode 100644
index 0000000..12942cf
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/debug/test/json/MyDebugEnum.java
@@ -0,0 +1,38 @@
+/******************************************************************************
+ * Copyright (c) 2016-2017 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.debug.test.json;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * DSP, unlike LSP enums are passed as strings, not numbers. That means a
+ * different style.
+ */
+public enum MyDebugEnum {
+
+	/**
+	 * An enum that simply needs case conversion
+	 */
+	ENUM1,
+
+	/**
+	 * An enum with _ case to camel case
+	 */
+	ANOTHER_ENUM,
+
+	/**
+	 * An enum with no fixed rule
+	 */
+	@SerializedName("aStrangeEnumUTC")
+	A_STRANGE_ENUM_UTC;
+
+}
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/test/ExtendableConcurrentMessageProcessorTest.java b/javatests/org/eclipse/lsp4j/jsonrpc/test/ExtendableConcurrentMessageProcessorTest.java
new file mode 100644
index 0000000..fdfd6b1
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/test/ExtendableConcurrentMessageProcessorTest.java
@@ -0,0 +1,267 @@
+/******************************************************************************
+ * Copyright (c) 2018 Red Hat Inc. and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.test;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.lsp4j.jsonrpc.Launcher;
+import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
+import org.eclipse.lsp4j.jsonrpc.MessageProducer;
+import org.eclipse.lsp4j.jsonrpc.Launcher.Builder;
+import org.eclipse.lsp4j.jsonrpc.json.ConcurrentMessageProcessor;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.services.JsonRequest;
+import org.eclipse.lsp4j.jsonrpc.test.ExtendableConcurrentMessageProcessorTest.MessageContextStore.MessageContext;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * This is a test to verify that it is easy for a client to override the construction
+ * of the ConcurrentMessageProcessor, so that an extender making use of 
+ * lsp4j.jsonrpc might be able to use these bootstrapping classes
+ * for different protocols that may need to identify which client is making
+ * each and every request. 
+ *
+ */
+public class ExtendableConcurrentMessageProcessorTest {
+	
+	private static final long TIMEOUT = 2000;
+
+	/**
+	 * Test that an adopter making use of these APIs is able to 
+	 * identify which client is making any given request. 
+	 */
+	@Test
+	public void testIdentifyClientRequest() throws Exception {
+		// create client side
+		PipedInputStream in = new PipedInputStream();
+		PipedOutputStream out = new PipedOutputStream();
+		PipedInputStream in2 = new PipedInputStream();
+		PipedOutputStream out2 = new PipedOutputStream();
+		
+		in.connect(out2);
+		out.connect(in2);
+		
+		MyClient client = new MyClientImpl();
+		Launcher<MyServer> clientSideLauncher = Launcher.createLauncher(client, MyServer.class, in, out);
+		
+		// create server side
+		MyServer server = new MyServerImpl();
+		MessageContextStore<MyClient> contextStore = new MessageContextStore<>();
+		Launcher<MyClient> serverSideLauncher = createLauncher(createBuilder(contextStore), server, MyClient.class, in2, out2);
+		
+		TestContextWrapper.setMap(contextStore);
+		
+		clientSideLauncher.startListening();
+		serverSideLauncher.startListening();
+		
+		CompletableFuture<MyParam> fooFuture = clientSideLauncher.getRemoteProxy().askServer(new MyParam("FOO"));
+		CompletableFuture<MyParam> barFuture = serverSideLauncher.getRemoteProxy().askClient(new MyParam("BAR"));
+		
+		Assert.assertEquals("FOO", fooFuture.get(TIMEOUT, TimeUnit.MILLISECONDS).value);
+		Assert.assertEquals("BAR", barFuture.get(TIMEOUT, TimeUnit.MILLISECONDS).value);
+		Assert.assertFalse(TestContextWrapper.error);
+	}
+	
+	/*
+	 * Copy the createLauncher method, but pass in a custom builder
+	 */
+	static <T> Launcher<T> createLauncher(Builder<T> builder, Object localService, Class<T> remoteInterface, InputStream in, OutputStream out) {
+		return builder.setLocalService(localService)
+				.setRemoteInterface(remoteInterface)
+				.setInput(in).setOutput(out)
+				.create();
+	}
+	
+	/*
+	 * The custom builder to be used when creating a launcher
+	 */
+	static <T> Builder<T> createBuilder(MessageContextStore<T> store) {
+		return new Builder<T>() {
+			@Override
+			protected ConcurrentMessageProcessor createMessageProcessor(MessageProducer reader, 
+					MessageConsumer messageConsumer, T remoteProxy) {
+				return new CustomConcurrentMessageProcessor<T>(reader, messageConsumer, remoteProxy, store);
+			}
+		};
+	}
+	
+	/*
+	 * The custom message processor, which can make sure to persist which clients are 
+	 * making a given request before propagating those requests to the server implementation. 
+	 */
+	public static class CustomConcurrentMessageProcessor<T> extends ConcurrentMessageProcessor {
+
+		private T remoteProxy;
+		private final MessageContextStore<T> threadMap;
+		public CustomConcurrentMessageProcessor(MessageProducer reader, MessageConsumer messageConsumer,
+				T remoteProxy, MessageContextStore<T> threadMap) {
+			super(reader, messageConsumer);
+			this.remoteProxy = remoteProxy;
+			this.threadMap = threadMap;
+		}
+
+		protected void processingStarted() {
+			super.processingStarted();
+			if (threadMap != null) {
+				threadMap.setContext(new MessageContext<T>(remoteProxy));
+			}
+		}
+
+		protected void processingEnded() {
+			super.processingEnded();
+			if (threadMap != null)
+				threadMap.clear();
+
+		}
+	}
+
+	/*
+	 * Server and client interfaces are below, along with any parameters required
+	 */
+
+	public static interface MyServer {
+		@JsonRequest
+		CompletableFuture<MyParam> askServer(MyParam param);
+	}
+	
+	public static interface MyClient {
+		@JsonRequest
+		CompletableFuture<MyParam> askClient(MyParam param);
+	}
+	public static class MyParam {
+		private MyParam nested;
+		private Either<String, Integer> either;
+
+		public MyParam() {}
+		
+		public MyParam(@NonNull String string) {
+			this.value = string;
+		}
+
+		@NonNull
+		private String value;
+		
+		@NonNull
+		public String getValue() {
+			return value;
+		}
+		
+		public void setValue(@NonNull String value) {
+			this.value = value;
+		}
+		
+		public MyParam getNested() {
+			return nested;
+		}
+
+		public void setNested(MyParam nested) {
+			this.nested = nested;
+		}
+
+		public Either<String, Integer> getEither() {
+			return either;
+		}
+
+		public void setEither(Either<String, Integer> either) {
+			this.either = either;
+		}
+	}
+
+	public static class MyServerImpl implements MyServer {
+		@Override
+		public CompletableFuture<MyParam> askServer(MyParam param) {
+			MessageContext<MyClient> context = TestContextWrapper.store.getContext();
+			MyClient client = context.getRemoteProxy();
+			if( client == null )
+				TestContextWrapper.setError(true);
+			else
+				TestContextWrapper.setError(false);
+			return CompletableFuture.completedFuture(param);
+		}
+	};
+
+	
+	public static class MyClientImpl implements MyClient {
+		@Override
+		public CompletableFuture<MyParam> askClient(MyParam param) {
+			return CompletableFuture.completedFuture(param);
+		}
+	};
+	
+	
+	/*
+	 * A custom class for storing the context for any given message
+	 */
+	public static class MessageContextStore<T> {
+		private ThreadLocal<MessageContext<T>> messageContext = new ThreadLocal<>();
+
+		public void setContext(MessageContext<T> context) {
+			messageContext.set(context);
+		}
+		
+		/**
+		 * Get the context for the current request
+		 * @return
+		 */
+		public MessageContext<T> getContext() {
+			return messageContext.get();
+		}
+		
+		/**
+		 * Remove the context for this request. 
+		 * Any new requests will need to set their context anew.
+		 */
+		public void clear() {
+			messageContext.remove();
+		}
+		
+		/**
+		 * This object can be extended to include whatever other context
+		 * from the raw message we may consider making available to implementations.
+		 * At a minimum, it should make available the remote proxy, so a given
+		 * request knows which remote proxy is making the request. 
+		 */
+		public static class MessageContext<T> {
+			T remoteProxy;
+			public MessageContext(T remoteProxy) {
+				this.remoteProxy = remoteProxy;
+			}
+			
+			public T getRemoteProxy() {
+				return this.remoteProxy;
+			}
+		};
+	}
+	
+	/*
+	 * A class used to store the results of the test (success or failure)
+	 */
+	public static class TestContextWrapper {
+		public static MessageContextStore<MyClient> store;
+		public static boolean error = false;
+		public static void setMap(MessageContextStore<MyClient> store2) {
+			store= store2;
+		}
+		
+		public static void setError(boolean error2) {
+			error = error2;
+		}
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/test/IntegrationTest.java b/javatests/org/eclipse/lsp4j/jsonrpc/test/IntegrationTest.java
new file mode 100644
index 0000000..eaf023b
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/test/IntegrationTest.java
@@ -0,0 +1,692 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.test;
+
+import static org.eclipse.lsp4j.jsonrpc.json.MessageConstants.CONTENT_LENGTH_HEADER;
+import static org.eclipse.lsp4j.jsonrpc.json.MessageConstants.CRLF;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.eclipse.lsp4j.jsonrpc.CompletableFutures;
+import org.eclipse.lsp4j.jsonrpc.Launcher;
+import org.eclipse.lsp4j.jsonrpc.RemoteEndpoint;
+import org.eclipse.lsp4j.jsonrpc.ResponseErrorException;
+import org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.services.GenericEndpoint;
+import org.eclipse.lsp4j.jsonrpc.services.JsonNotification;
+import org.eclipse.lsp4j.jsonrpc.services.JsonRequest;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class IntegrationTest {
+	
+	private static final long TIMEOUT = 2000;
+
+	public static class MyParam {
+		public MyParam() {}
+		
+		public MyParam(@NonNull String string) {
+			this.value = string;
+		}
+
+		@NonNull
+		private String value;
+		
+		@NonNull
+		public String getValue() {
+			return value;
+		}
+		
+		public void setValue(@NonNull String value) {
+			this.value = value;
+		}
+		
+		private MyParam nested;
+
+		public MyParam getNested() {
+			return nested;
+		}
+
+		public void setNested(MyParam nested) {
+			this.nested = nested;
+		}
+
+		private Either<String, Integer> either;
+
+		public Either<String, Integer> getEither() {
+			return either;
+		}
+
+		public void setEither(Either<String, Integer> either) {
+			this.either = either;
+		}
+	}
+
+	public static interface MyServer {
+		@JsonRequest
+		CompletableFuture<MyParam> askServer(MyParam param);
+	}
+	
+	public static class MyServerImpl implements MyServer {
+		@Override
+		public CompletableFuture<MyParam> askServer(MyParam param) {
+			return CompletableFuture.completedFuture(param);
+		}
+	};
+
+	public static interface MyClient {
+		@JsonRequest
+		CompletableFuture<MyParam> askClient(MyParam param);
+	}
+	
+	public static class MyClientImpl implements MyClient {
+		@Override
+		public CompletableFuture<MyParam> askClient(MyParam param) {
+			return CompletableFuture.completedFuture(param);
+		}
+	};
+
+	@Test
+	public void testBothDirectionRequests() throws Exception {
+		// create client side
+		PipedInputStream in = new PipedInputStream();
+		PipedOutputStream out = new PipedOutputStream();
+		PipedInputStream in2 = new PipedInputStream();
+		PipedOutputStream out2 = new PipedOutputStream();
+		
+		in.connect(out2);
+		out.connect(in2);
+		
+		MyClient client = new MyClientImpl();
+		Launcher<MyServer> clientSideLauncher = Launcher.createLauncher(client, MyServer.class, in, out);
+		
+		// create server side
+		MyServer server = new MyServerImpl();
+		Launcher<MyClient> serverSideLauncher = Launcher.createLauncher(server, MyClient.class, in2, out2);
+		
+		clientSideLauncher.startListening();
+		serverSideLauncher.startListening();
+		
+		CompletableFuture<MyParam> fooFuture = clientSideLauncher.getRemoteProxy().askServer(new MyParam("FOO"));
+		CompletableFuture<MyParam> barFuture = serverSideLauncher.getRemoteProxy().askClient(new MyParam("BAR"));
+		
+		Assert.assertEquals("FOO", fooFuture.get(TIMEOUT, TimeUnit.MILLISECONDS).value);
+		Assert.assertEquals("BAR", barFuture.get(TIMEOUT, TimeUnit.MILLISECONDS).value);
+	}
+
+	@Test
+	public void testResponse1() throws Exception {
+		// create client message
+		String requestMessage = "{\"jsonrpc\": \"2.0\",\n"
+				+ "\"id\": \"42\",\n" 
+				+ "\"method\": \"askServer\",\n" 
+				+ "\"params\": { \"value\": \"bar\" }\n"
+				+ "}";
+		String clientMessage = getHeader(requestMessage.getBytes().length) + requestMessage;
+		
+		// create server side
+		ByteArrayInputStream in = new ByteArrayInputStream(clientMessage.getBytes());
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		MyServer server = new MyServerImpl();
+		Launcher<MyClient> serverSideLauncher = Launcher.createLauncher(server, MyClient.class, in, out);
+		serverSideLauncher.startListening().get(TIMEOUT, TimeUnit.MILLISECONDS);
+		
+		Assert.assertEquals("Content-Length: 52" + CRLF + CRLF
+				+ "{\"jsonrpc\":\"2.0\",\"id\":\"42\",\"result\":{\"value\":\"bar\"}}",
+				out.toString());
+	}
+	
+	@Test
+	public void testResponse2() throws Exception {
+		// create client message
+		String requestMessage = "{\"jsonrpc\": \"2.0\",\n"
+				+ "\"id\": 42,\n" 
+				+ "\"method\": \"askServer\",\n" 
+				+ "\"params\": { \"value\": \"bar\" }\n"
+				+ "}";
+		String clientMessage = getHeader(requestMessage.getBytes().length) + requestMessage;
+		
+		// create server side
+		ByteArrayInputStream in = new ByteArrayInputStream(clientMessage.getBytes());
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		MyServer server = new MyServerImpl();
+		Launcher<MyClient> serverSideLauncher = Launcher.createLauncher(server, MyClient.class, in, out);
+		serverSideLauncher.startListening().get(TIMEOUT, TimeUnit.MILLISECONDS);
+		
+		Assert.assertEquals("Content-Length: 50" + CRLF + CRLF
+				+ "{\"jsonrpc\":\"2.0\",\"id\":42,\"result\":{\"value\":\"bar\"}}",
+				out.toString());
+	}
+
+	@Test
+	public void testEither() throws Exception {
+		// create client message
+		String requestMessage = "{\"jsonrpc\": \"2.0\",\n"
+				+ "\"id\": 42,\n"
+				+ "\"method\": \"askServer\",\n"
+				+ "\"params\": { \"either\": \"bar\", \"value\": \"foo\" }\n"
+				+ "}";
+		String clientMessage = getHeader(requestMessage.getBytes().length) + requestMessage;
+
+		// create server side
+		ByteArrayInputStream in = new ByteArrayInputStream(clientMessage.getBytes());
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		MyServer server = new MyServerImpl();
+		Launcher<MyClient> serverSideLauncher = Launcher.createLauncher(server, MyClient.class, in, out);
+		serverSideLauncher.startListening().get(TIMEOUT, TimeUnit.MILLISECONDS);
+
+		Assert.assertEquals("Content-Length: 65" + CRLF + CRLF
+				+ "{\"jsonrpc\":\"2.0\",\"id\":42,\"result\":{\"value\":\"foo\",\"either\":\"bar\"}}",
+				out.toString());
+	}
+
+	@Test
+	public void testEitherNull() throws Exception {
+		// create client message
+		String requestMessage = "{\"jsonrpc\": \"2.0\",\n"
+				+ "\"id\": 42,\n"
+				+ "\"method\": \"askServer\",\n"
+				+ "\"params\": { \"either\": null, \"value\": \"foo\" }\n"
+				+ "}";
+		String clientMessage = getHeader(requestMessage.getBytes().length) + requestMessage;
+
+		// create server side
+		ByteArrayInputStream in = new ByteArrayInputStream(clientMessage.getBytes());
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		MyServer server = new MyServerImpl();
+		Launcher<MyClient> serverSideLauncher = Launcher.createLauncher(server, MyClient.class, in, out);
+		serverSideLauncher.startListening().get(TIMEOUT, TimeUnit.MILLISECONDS);
+
+		Assert.assertEquals("Content-Length: 50" + CRLF + CRLF
+				+ "{\"jsonrpc\":\"2.0\",\"id\":42,\"result\":{\"value\":\"foo\"}}",
+				out.toString());
+	}
+
+
+	@Test
+	public void testCancellation() throws Exception {
+		// create client side
+		PipedInputStream in = new PipedInputStream();
+		PipedOutputStream out = new PipedOutputStream();
+		PipedInputStream in2 = new PipedInputStream();
+		PipedOutputStream out2 = new PipedOutputStream();
+		
+		in.connect(out2);
+		out.connect(in2);
+
+		boolean[] inComputeAsync = new boolean[1];
+		boolean[] cancellationHappened = new boolean[1];
+		
+		MyClient client = new MyClient() {
+			@Override
+			public CompletableFuture<MyParam> askClient(MyParam param) {
+				return CompletableFutures.computeAsync(cancelToken -> {
+					try {
+						long startTime = System.currentTimeMillis();
+						inComputeAsync[0] = true;
+						do {
+							cancelToken.checkCanceled();
+							Thread.sleep(50);
+						} while (System.currentTimeMillis() - startTime < TIMEOUT);
+					} catch (CancellationException e) {
+						cancellationHappened[0] = true;
+					} catch (InterruptedException e) {
+						Assert.fail("Thread was interrupted unexpectedly.");
+					}
+					return param;
+				});
+			}
+		};
+		Launcher<MyServer> clientSideLauncher = Launcher.createLauncher(client, MyServer.class, in, out);
+		
+		// create server side
+		MyServer server = new MyServerImpl();
+		Launcher<MyClient> serverSideLauncher = Launcher.createLauncher(server, MyClient.class, in2, out2);
+		
+		clientSideLauncher.startListening();
+		serverSideLauncher.startListening();
+		
+		CompletableFuture<MyParam> future = serverSideLauncher.getRemoteProxy().askClient(new MyParam("FOO"));
+
+		long startTime = System.currentTimeMillis();
+		while (!inComputeAsync[0]) {
+			Thread.sleep(50);
+			if (System.currentTimeMillis() - startTime > TIMEOUT)
+				Assert.fail("Timeout waiting for client to start computing.");
+		}
+		future.cancel(true);
+
+		startTime = System.currentTimeMillis();
+		while (!cancellationHappened[0]) {
+			Thread.sleep(50);
+			if (System.currentTimeMillis() - startTime > TIMEOUT)
+				Assert.fail("Timeout waiting for confirmation of cancellation.");
+		}
+		try {
+			future.get(TIMEOUT, TimeUnit.MILLISECONDS);
+			Assert.fail("Expected cancellation.");
+		} catch (CancellationException e) {
+		}
+	}
+	
+	@Test
+	public void testCancellationResponse() throws Exception {
+		// create client messages
+		String requestMessage = "{\"jsonrpc\": \"2.0\",\n"
+				+ "\"id\": \"1\",\n" 
+				+ "\"method\": \"askServer\",\n" 
+				+ "\"params\": { \"value\": \"bar\" }\n"
+				+ "}";
+		String cancellationMessage = "{\"jsonrpc\": \"2.0\",\n"
+				+ "\"method\": \"$/cancelRequest\",\n" 
+				+ "\"params\": { \"id\": 1 }\n"
+				+ "}";
+		String clientMessages = getHeader(requestMessage.getBytes().length) + requestMessage
+				+ getHeader(cancellationMessage.getBytes().length) + cancellationMessage;
+		
+		// create server side
+		ByteArrayInputStream in = new ByteArrayInputStream(clientMessages.getBytes());
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		MyServer server = new MyServer() {
+			@Override
+			public CompletableFuture<MyParam> askServer(MyParam param) {
+				return CompletableFutures.computeAsync(cancelToken -> {
+					try {
+						long startTime = System.currentTimeMillis();
+						do {
+							cancelToken.checkCanceled();
+							Thread.sleep(50);
+						} while (System.currentTimeMillis() - startTime < TIMEOUT);
+					} catch (InterruptedException e) {
+						Assert.fail("Thread was interrupted unexpectedly.");
+					}
+					return param;
+				});
+			}
+		};
+		Launcher<MyClient> serverSideLauncher = Launcher.createLauncher(server, MyClient.class, in, out);
+		serverSideLauncher.startListening().get(TIMEOUT, TimeUnit.MILLISECONDS);
+		
+		Assert.assertEquals("Content-Length: 132" + CRLF + CRLF
+				+ "{\"jsonrpc\":\"2.0\",\"id\":\"1\",\"error\":{\"code\":-32800,\"message\":\"The request (id: 1, method: \\u0027askServer\\u0027) has been cancelled\"}}",
+				out.toString());
+	}
+
+	@Test
+	public void testVersatility() throws Exception {
+		Logger.getLogger(RemoteEndpoint.class.getName()).setLevel(Level.OFF);
+		// create client side
+		PipedInputStream in = new PipedInputStream();
+		PipedOutputStream out = new PipedOutputStream();
+		PipedInputStream in2 = new PipedInputStream();
+		PipedOutputStream out2 = new PipedOutputStream();
+		
+		// See https://github.com/eclipse/lsp4j/issues/510 for full details.
+		// Make sure that the thread that writes to the PipedOutputStream stays alive
+		// until the read from the PipedInputStream. Using a cached thread pool
+		// does not 100% guarantee that, but increases the probability that the
+		// selected thread will exist for the lifetime of the test.
+		ExecutorService executor = Executors.newCachedThreadPool();
+
+		in.connect(out2);
+		out.connect(in2);
+		
+		MyClient client = new MyClient() {
+			private int tries = 0;
+			
+			@Override
+			public CompletableFuture<MyParam> askClient(MyParam param) {
+				if (tries == 0) {
+					tries++;
+					throw new UnsupportedOperationException();
+				}
+				return CompletableFutures.computeAsync(executor, cancelToken -> {
+					if (tries++ == 1)
+						throw new UnsupportedOperationException();
+					return param;
+				});
+			}
+		};
+		Launcher<MyServer> clientSideLauncher = Launcher.createLauncher(client, MyServer.class, in, out);
+		
+		// create server side
+		MyServer server = new MyServerImpl();
+		Launcher<MyClient> serverSideLauncher = Launcher.createLauncher(server, MyClient.class, in2, out2);
+		
+		clientSideLauncher.startListening();
+		serverSideLauncher.startListening();
+		
+		CompletableFuture<MyParam> errorFuture1 = serverSideLauncher.getRemoteProxy().askClient(new MyParam("FOO"));
+		try {
+			System.out.println(errorFuture1.get());
+			Assert.fail();
+		} catch (ExecutionException e) {
+			Assert.assertNotNull(((ResponseErrorException)e.getCause()).getResponseError().getMessage());
+		}
+		CompletableFuture<MyParam> errorFuture2 = serverSideLauncher.getRemoteProxy().askClient(new MyParam("FOO"));
+		try {
+			errorFuture2.get();
+			Assert.fail();
+		} catch (ExecutionException e) {
+			Assert.assertNotNull(((ResponseErrorException)e.getCause()).getResponseError().getMessage());
+		}
+		CompletableFuture<MyParam> goodFuture = serverSideLauncher.getRemoteProxy().askClient(new MyParam("FOO"));
+		Assert.assertEquals("FOO", goodFuture.get(TIMEOUT, TimeUnit.MILLISECONDS).value);
+	}
+
+	@Test
+	public void testUnknownMessages() throws Exception {
+		// intercept log messages
+		LogMessageAccumulator logMessages = new LogMessageAccumulator();
+		try {
+			logMessages.registerTo(GenericEndpoint.class);
+			
+			// create client messages
+			String clientMessage1 = "{\"jsonrpc\": \"2.0\",\n"
+					+ "\"method\": \"foo1\",\n" 
+					+ "\"params\": \"bar\"\n"
+					+ "}";
+			String clientMessage2 = "{\"jsonrpc\": \"2.0\",\n"
+					+ "\"id\": \"1\",\n" 
+					+ "\"method\": \"foo2\",\n" 
+					+ "\"params\": \"bar\"\n"
+					+ "}";
+			String clientMessages = getHeader(clientMessage1.getBytes().length) + clientMessage1
+					+ getHeader(clientMessage2.getBytes().length) + clientMessage2;
+			
+			// create server side
+			ByteArrayInputStream in = new ByteArrayInputStream(clientMessages.getBytes());
+			ByteArrayOutputStream out = new ByteArrayOutputStream();
+			MyServer server = new MyServerImpl();
+			Launcher<MyClient> serverSideLauncher = Launcher.createLauncher(server, MyClient.class, in, out);
+			serverSideLauncher.startListening().get(TIMEOUT, TimeUnit.MILLISECONDS);
+			
+			logMessages.await(Level.WARNING, "Unsupported notification method: foo1");
+			logMessages.await(Level.WARNING, "Unsupported request method: foo2");
+			
+			Assert.assertEquals("Content-Length: 95" + CRLF + CRLF
+					+ "{\"jsonrpc\":\"2.0\",\"id\":\"1\",\"error\":{\"code\":-32601,\"message\":\"Unsupported request method: foo2\"}}",
+					out.toString());
+		} finally {
+			logMessages.unregister();
+		}
+	}
+	
+	@Test
+	public void testUnknownOptionalMessages() throws Exception {
+		// intercept log messages
+		LogMessageAccumulator logMessages = new LogMessageAccumulator();
+		try {
+			logMessages.registerTo(GenericEndpoint.class);
+			
+			// create client messages
+			String clientMessage1 = "{\"jsonrpc\": \"2.0\",\n"
+					+ "\"method\": \"$/foo1\",\n" 
+					+ "\"params\": \"bar\"\n"
+					+ "}";
+			String clientMessage2 = "{\"jsonrpc\": \"2.0\",\n"
+					+ "\"id\": \"1\",\n" 
+					+ "\"method\": \"$/foo2\",\n" 
+					+ "\"params\": \"bar\"\n"
+					+ "}";
+			String clientMessages = getHeader(clientMessage1.getBytes().length) + clientMessage1
+					+ getHeader(clientMessage2.getBytes().length) + clientMessage2;
+			
+			// create server side
+			ByteArrayInputStream in = new ByteArrayInputStream(clientMessages.getBytes());
+			ByteArrayOutputStream out = new ByteArrayOutputStream();
+			MyServer server = new MyServerImpl();
+			Launcher<MyClient> serverSideLauncher = Launcher.createLauncher(server, MyClient.class, in, out);
+			serverSideLauncher.startListening().get(TIMEOUT, TimeUnit.MILLISECONDS);
+			
+			logMessages.await(Level.INFO, "Unsupported notification method: $/foo1");
+			logMessages.await(Level.INFO, "Unsupported request method: $/foo2");
+			
+			Assert.assertEquals("Content-Length: 40" + CRLF + CRLF
+					+ "{\"jsonrpc\":\"2.0\",\"id\":\"1\",\"result\":null}",
+					out.toString());
+		} finally {
+			logMessages.unregister();
+		}
+	}
+	
+	public static interface UnexpectedParamsTestServer {
+		@JsonNotification
+		void myNotification();
+	}
+	
+	@Test
+	public void testUnexpectedParams() throws Exception {
+		// intercept log messages
+		LogMessageAccumulator logMessages = new LogMessageAccumulator();
+		try {
+			logMessages.registerTo(GenericEndpoint.class);
+			
+			// create client messages
+			String notificationMessage = "{\"jsonrpc\": \"2.0\",\n"
+					+ "\"method\": \"myNotification\",\n" 
+					+ "\"params\": { \"value\": \"foo\" }\n"
+					+ "}";
+			String clientMessages = getHeader(notificationMessage.getBytes().length) + notificationMessage;
+			
+			// create server side
+			ByteArrayInputStream in = new ByteArrayInputStream(clientMessages.getBytes());
+			ByteArrayOutputStream out = new ByteArrayOutputStream();
+			UnexpectedParamsTestServer server = new UnexpectedParamsTestServer() {
+				public void myNotification() {
+				}
+			};
+			Launcher<MyClient> serverSideLauncher = Launcher.createLauncher(server, MyClient.class, in, out);
+			serverSideLauncher.startListening();
+			
+			logMessages.await(Level.WARNING, "Unexpected params '{\"value\":\"foo\"}' for "
+					+ "'public abstract void org.eclipse.lsp4j.jsonrpc.test.IntegrationTest$UnexpectedParamsTestServer.myNotification()' is ignored");
+		} finally {
+			logMessages.unregister();
+		}
+	}
+	
+	@Test
+	public void testMalformedJson1() throws Exception {
+		String requestMessage1 = "{\"jsonrpc\": \"2.0\",\n"
+				+ "\"id\": \"1\",\n" 
+				+ "\"method\": \"askServer\",\n" 
+				+ "\"params\": { \"value\": }\n"
+				+ "}";
+		String requestMessage2 = "{\"jsonrpc\": \"2.0\",\n"
+				+ "\"id\": \"2\",\n" 
+				+ "\"method\": \"askServer\",\n" 
+				+ "\"params\": { \"value\": \"bar\" }\n"
+				+ "}";
+		String clientMessages = getHeader(requestMessage1.getBytes().length) + requestMessage1
+				+ getHeader(requestMessage2.getBytes().length) + requestMessage2;
+		
+		ByteArrayInputStream in = new ByteArrayInputStream(clientMessages.getBytes());
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		MyServer server = new MyServerImpl();
+		Launcher<MyClient> serverSideLauncher = Launcher.createLauncher(server, MyClient.class, in, out);
+		serverSideLauncher.startListening().get(TIMEOUT, TimeUnit.MILLISECONDS);
+		
+		Assert.assertEquals("Content-Length: 214" + CRLF + CRLF
+				+ "{\"jsonrpc\":\"2.0\",\"id\":\"1\",\"error\":{\"code\":-32700,\"message\":\"Message could not be parsed.\","
+				+    "\"data\":{\"message\":\"com.google.gson.stream.MalformedJsonException: Expected value at line 4 column 22 path $.params.value\"}}}"
+				+ "Content-Length: 51" + CRLF + CRLF
+				+ "{\"jsonrpc\":\"2.0\",\"id\":\"2\",\"result\":{\"value\":\"bar\"}}",
+				out.toString());
+	}
+	
+	@Test
+	public void testMalformedJson2() throws Exception {
+		// intercept log messages
+		LogMessageAccumulator logMessages = new LogMessageAccumulator();
+		try {
+			logMessages.registerTo(StreamMessageProducer.class);
+			
+			String requestMessage1 = "{\"jsonrpc\": \"2.0\",\n"
+					+ "\"params\": { \"value\": }\n"
+					+ "\"id\": \"1\",\n" 
+					+ "\"method\":\"askServer\",\n" 
+					+ "}";
+			String requestMessage2 = "{\"jsonrpc\": \"2.0\",\n"
+					+ "\"id\": \"2\",\n" 
+					+ "\"method\": \"askServer\",\n" 
+					+ "\"params\": { \"value\": \"bar\" }\n"
+					+ "}";
+			String clientMessages = getHeader(requestMessage1.getBytes().length) + requestMessage1
+					+ getHeader(requestMessage2.getBytes().length) + requestMessage2;
+			
+			ByteArrayInputStream in = new ByteArrayInputStream(clientMessages.getBytes());
+			ByteArrayOutputStream out = new ByteArrayOutputStream();
+			MyServer server = new MyServerImpl();
+			Launcher<MyClient> serverSideLauncher = Launcher.createLauncher(server, MyClient.class, in, out);
+			serverSideLauncher.startListening().get(TIMEOUT, TimeUnit.MILLISECONDS);
+			
+			logMessages.await(Level.SEVERE, "com.google.gson.stream.MalformedJsonException: Expected value at line 2 column 22 path $.params.value");
+			Assert.assertEquals("Content-Length: 51" + CRLF + CRLF
+					+ "{\"jsonrpc\":\"2.0\",\"id\":\"2\",\"result\":{\"value\":\"bar\"}}",
+					out.toString());
+		} finally {
+			logMessages.unregister();
+		}
+	}
+	
+	@Test
+	public void testMalformedJson3() throws Exception {
+		String requestMessage1 = "{\"jsonrpc\": \"2.0\",\n"
+				+ "\"id\": \"1\",\n" 
+				+ "\"method\": \"askServer\",\n" 
+				+ "\"params\": { \"value\": \"bar\" }\n"
+				+ "]";
+		String requestMessage2 = "{\"jsonrpc\": \"2.0\",\n"
+				+ "\"id\": \"2\",\n" 
+				+ "\"method\": \"askServer\",\n" 
+				+ "\"params\": { \"value\": \"bar\" }\n"
+				+ "}";
+		String clientMessages = getHeader(requestMessage1.getBytes().length) + requestMessage1
+				+ getHeader(requestMessage2.getBytes().length) + requestMessage2;
+		
+		ByteArrayInputStream in = new ByteArrayInputStream(clientMessages.getBytes());
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		MyServer server = new MyServerImpl();
+		Launcher<MyClient> serverSideLauncher = Launcher.createLauncher(server, MyClient.class, in, out);
+		serverSideLauncher.startListening().get(TIMEOUT, TimeUnit.MILLISECONDS);
+		
+		Assert.assertEquals("Content-Length: 165" + CRLF + CRLF
+				+ "{\"jsonrpc\":\"2.0\",\"id\":\"1\",\"error\":{\"code\":-32700,\"message\":\"Message could not be parsed.\","
+				+    "\"data\":{\"message\":\"Unterminated object at line 5 column 2 path $.params\"}}}"
+				+ "Content-Length: 51" + CRLF + CRLF
+				+ "{\"jsonrpc\":\"2.0\",\"id\":\"2\",\"result\":{\"value\":\"bar\"}}",
+				out.toString());
+	}
+	
+	@Test
+	public void testMalformedJson4() throws Exception {
+		String requestMessage1 = "{\"jsonrpc\": \"2.0\",\n"
+				+ "\"id\": \"1\",\n" 
+				+ "\"method\": \"askServer\",\n" 
+				+ "\"params\": { \"value\": \"bar\" }\n"
+				+ "}}";
+		String requestMessage2 = "{\"jsonrpc\":\"2.0\",\n"
+				+ "\"id\":\"2\",\n" 
+				+ "\"method\":\"askServer\",\n" 
+				+ "\"params\": { \"value\": \"bar\" }\n"
+				+ "}";
+		String clientMessages = getHeader(requestMessage1.getBytes().length) + requestMessage1
+				+ getHeader(requestMessage2.getBytes().length) + requestMessage2;
+		
+		ByteArrayInputStream in = new ByteArrayInputStream(clientMessages.getBytes());
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		MyServer server = new MyServerImpl();
+		Launcher<MyClient> serverSideLauncher = Launcher.createLauncher(server, MyClient.class, in, out);
+		serverSideLauncher.startListening().get(TIMEOUT, TimeUnit.MILLISECONDS);
+		
+		Assert.assertEquals("Content-Length: 195" + CRLF + CRLF
+				+ "{\"jsonrpc\":\"2.0\",\"id\":\"1\",\"error\":{\"code\":-32700,\"message\":\"Message could not be parsed.\","
+				+    "\"data\":{\"message\":\"Use JsonReader.setLenient(true) to accept malformed JSON at line 5 column 3 path $\"}}}"
+				+ "Content-Length: 51" + CRLF + CRLF
+				+ "{\"jsonrpc\":\"2.0\",\"id\":\"2\",\"result\":{\"value\":\"bar\"}}",
+				out.toString());
+	}
+	
+	@Test
+	public void testValidationIssue1() throws Exception {
+		String requestMessage1 = "{\"jsonrpc\": \"2.0\",\n"
+				+ "\"id\": \"1\",\n" 
+				+ "\"method\": \"askServer\",\n" 
+				+ "\"params\": { \"value\": null }\n"
+				+ "}";
+		String requestMessage2 = "{\"jsonrpc\": \"2.0\",\n"
+				+ "\"id\": \"2\",\n" 
+				+ "\"method\": \"askServer\",\n" 
+				+ "\"params\": { \"value\": \"bar\" }\n"
+				+ "}";
+		String clientMessages = getHeader(requestMessage1.getBytes().length) + requestMessage1
+				+ getHeader(requestMessage2.getBytes().length) + requestMessage2;
+		
+		ByteArrayInputStream in = new ByteArrayInputStream(clientMessages.getBytes());
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		MyServer server = new MyServerImpl();
+		Launcher<MyClient> serverSideLauncher = Launcher.createLauncher(server, MyClient.class, in, out, true, null);
+		serverSideLauncher.startListening().get(TIMEOUT, TimeUnit.MILLISECONDS);
+		
+		Assert.assertEquals("Content-Length: 157" + CRLF + CRLF
+				+ "{\"jsonrpc\":\"2.0\",\"id\":\"1\",\"error\":{\"code\":-32602,\"message\":\"The accessor \\u0027MyParam.getValue()\\u0027 must return a non-null value. Path: $.params.value\"}}"
+				+ "Content-Length: 51" + CRLF + CRLF
+				+ "{\"jsonrpc\":\"2.0\",\"id\":\"2\",\"result\":{\"value\":\"bar\"}}",
+				out.toString());
+	}
+	
+	@Test
+	public void testValidationIssue2() throws Exception {
+		String requestMessage1 = "{\"jsonrpc\": \"2.0\",\n"
+				+ "\"id\": \"1\",\n" 
+				+ "\"method\": \"askServer\",\n" 
+				+ "\"params\": { \"value\": null, \"nested\": { \"value\": null } }\n"
+				+ "}";
+		String clientMessages = getHeader(requestMessage1.getBytes().length) + requestMessage1;
+		
+		ByteArrayInputStream in = new ByteArrayInputStream(clientMessages.getBytes());
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		MyServer server = new MyServerImpl();
+		Launcher<MyClient> serverSideLauncher = Launcher.createLauncher(server, MyClient.class, in, out, true, null);
+		serverSideLauncher.startListening().get(TIMEOUT, TimeUnit.MILLISECONDS);
+		
+		Assert.assertEquals("Content-Length: 379" + CRLF + CRLF
+				+ "{\"jsonrpc\":\"2.0\",\"id\":\"1\",\"error\":{\"code\":-32600,\"message\":\"Multiple issues were found in \\u0027askServer\\u0027 request.\","
+				+ "\"data\":["
+				+    "{\"text\":\"The accessor \\u0027MyParam.getValue()\\u0027 must return a non-null value. Path: $.params.nested.value\",\"code\":-32602},"
+				+    "{\"text\":\"The accessor \\u0027MyParam.getValue()\\u0027 must return a non-null value. Path: $.params.value\",\"code\":-32602}"
+				+ "]}}",
+				out.toString());
+	}
+
+	protected String getHeader(int contentLength) {
+		StringBuilder headerBuilder = new StringBuilder();
+		headerBuilder.append(CONTENT_LENGTH_HEADER).append(": ").append(contentLength).append(CRLF);
+		headerBuilder.append(CRLF);
+		return headerBuilder.toString();
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/test/LauncherTest.java b/javatests/org/eclipse/lsp4j/jsonrpc/test/LauncherTest.java
new file mode 100644
index 0000000..c7d9924
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/test/LauncherTest.java
@@ -0,0 +1,169 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.test;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.lsp4j.jsonrpc.Launcher;
+import org.eclipse.lsp4j.jsonrpc.services.JsonNotification;
+import org.eclipse.lsp4j.jsonrpc.services.JsonRequest;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+
+public class LauncherTest {
+	
+	private static final long TIMEOUT = 2000;
+	
+	static class Param {
+		Param() {
+		}
+		Param(String message) {
+			this.message = message;
+		}
+		public String message;
+	}
+	
+	static interface A {
+		@JsonNotification
+		public void say(Param p);
+	}
+	
+	static interface B {
+		@JsonRequest
+		public CompletableFuture<String> ask(Param p);
+	}
+
+	@Test public void testDone() throws Exception {
+		A a = new A() {
+			@Override
+			public void say(Param p) {
+			}
+		};
+		Launcher<A> launcher = Launcher.createLauncher(a, A.class, new ByteArrayInputStream("".getBytes()), new ByteArrayOutputStream());
+		Future<?> startListening = launcher.startListening();
+		startListening.get(TIMEOUT, TimeUnit.MILLISECONDS);
+		Assert.assertTrue(startListening.isDone());
+		Assert.assertFalse(startListening.isCancelled());
+	}
+	
+	@Test public void testCanceled() throws Exception {
+		A a = new A() {
+			@Override
+			public void say(Param p) {
+			}
+		};
+		Launcher<A> launcher = Launcher.createLauncher(a, A.class, new InputStream() {
+			@Override
+			public int read() throws IOException {
+				try {
+					Thread.sleep(100);
+				} catch (InterruptedException e) {
+					throw new RuntimeException(e);
+				}
+				return '\n';
+			}
+		}, new ByteArrayOutputStream());
+		Future<?> startListening = launcher.startListening();
+		startListening.cancel(true);
+		Assert.assertTrue(startListening.isDone());
+		Assert.assertTrue(startListening.isCancelled());
+	}
+	
+	@Test public void testCustomGson() throws Exception {
+		A a = new A() {
+			@Override
+			public void say(Param p) {
+			}
+		};
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		TypeAdapter<Param> typeAdapter = new TypeAdapter<Param>() {
+			@Override
+			public void write(JsonWriter out, Param value) throws IOException {
+				out.beginObject();
+				out.name("message");
+				out.value("bar");
+				out.endObject();
+			}
+			@Override
+			public Param read(JsonReader in) throws IOException {
+				return null;
+			}
+		};
+		Launcher<A> launcher = Launcher.createIoLauncher(a, A.class, new ByteArrayInputStream("".getBytes()), out,
+				Executors.newCachedThreadPool(), c -> c,
+				gsonBuilder -> {gsonBuilder.registerTypeAdapter(Param.class, typeAdapter);});
+		A remoteProxy = launcher.getRemoteProxy();
+		
+		remoteProxy.say(new Param("foo"));
+		Assert.assertEquals("Content-Length: 59\r\n\r\n"
+				+ "{\"jsonrpc\":\"2.0\",\"method\":\"say\",\"params\":{\"message\":\"bar\"}}",
+				out.toString());
+	}
+	
+	@Test public void testMultipleServices() throws Exception {
+		final String[] paramA = new String[1];
+		A a = new A() {
+			@Override
+			public void say(Param p) {
+				paramA[0] = p.message;
+			}
+		};
+		final String[] paramB = new String[1];
+		B b = new B() {
+			@Override
+			public CompletableFuture<String> ask(Param p) {
+				paramB[0] = p.message;
+				return CompletableFuture.completedFuture("echo " + p.message);
+			}
+		};
+		String inputMessages = "Content-Length: 60\r\n\r\n"
+			+ "{\"jsonrpc\":\"2.0\",\"method\":\"say\",\"params\":{\"message\":\"foo1\"}}"
+			+ "Content-Length: 69\r\n\r\n"
+			+ "{\"jsonrpc\":\"2.0\",\"id\":\"1\",\"method\":\"ask\",\"params\":{\"message\":\"bar1\"}}";
+		ByteArrayInputStream in = new ByteArrayInputStream(inputMessages.getBytes());
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		
+		ClassLoader classLoader = getClass().getClassLoader();
+		Launcher<Object> launcher = Launcher.createIoLauncher(Arrays.asList(a, b), Arrays.asList(A.class, B.class),
+				classLoader, in, out, Executors.newCachedThreadPool(), c -> c, null);
+		
+		launcher.startListening().get(TIMEOUT, TimeUnit.MILLISECONDS);
+		assertEquals("foo1", paramA[0]);
+		assertEquals("bar1", paramB[0]);
+		
+		Object remoteProxy = launcher.getRemoteProxy();
+		((A) remoteProxy).say(new Param("foo2"));
+		((B) remoteProxy).ask(new Param("bar2"));
+		Assert.assertEquals("Content-Length: 47\r\n\r\n" 
+				+ "{\"jsonrpc\":\"2.0\",\"id\":\"1\",\"result\":\"echo bar1\"}"
+				+ "Content-Length: 60\r\n\r\n"
+				+ "{\"jsonrpc\":\"2.0\",\"method\":\"say\",\"params\":{\"message\":\"foo2\"}}"
+				+ "Content-Length: 69\r\n\r\n"
+				+ "{\"jsonrpc\":\"2.0\",\"id\":\"1\",\"method\":\"ask\",\"params\":{\"message\":\"bar2\"}}",
+				out.toString());
+	}
+	
+}
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/test/LogMessageAccumulator.java b/javatests/org/eclipse/lsp4j/jsonrpc/test/LogMessageAccumulator.java
new file mode 100644
index 0000000..c850c17
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/test/LogMessageAccumulator.java
@@ -0,0 +1,120 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Predicate;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+
+import org.junit.Assert;
+
+public class LogMessageAccumulator extends Handler {
+	
+	private static final long TIMEOUT = 2000;
+	
+	private final List<LogRecord> records = new ArrayList<>();
+	private final List<Logger> registeredLoggers = new ArrayList<>();
+	
+	public Logger registerTo(Class<?> clazz) {
+		return registerTo(clazz.getName());
+	}
+	
+	public Logger registerTo(String name) {
+		Logger logger = Logger.getLogger(name);
+		logger.setUseParentHandlers(false);
+		logger.addHandler(this);
+		logger.setLevel(Level.ALL);
+		registeredLoggers.add(logger);
+		return logger;
+	}
+	
+	public void unregister() {
+		for (Logger logger : registeredLoggers) {
+			logger.setLevel(null);
+			logger.removeHandler(this);
+			logger.setUseParentHandlers(true);
+		}
+		registeredLoggers.clear();
+	}
+	
+	public List<LogRecord> getRecords() {
+		return records;
+	}
+	
+	public LogRecord findRecord(Level level, String message) {
+		synchronized (records) {
+			for (LogRecord r : records) {
+				if (level.equals(r.getLevel()) && message.equals(r.getMessage()))
+					return r;
+			}
+			return null;
+		}
+	}
+	
+	public Optional<LogRecord> match(Predicate<LogRecord> predicate) {
+		synchronized (records) {
+			return records.stream().filter(predicate).findFirst();
+		}
+	} 
+
+	@Override
+	public void publish(LogRecord record) {
+		synchronized (records) {
+			records.add(record);
+		}
+	}
+
+	@Override
+	public void flush() {
+	}
+
+	@Override
+	public void close() throws SecurityException {
+	}
+
+	public void await(Predicate<LogRecord> predicate) throws InterruptedException {
+		long startTime = System.currentTimeMillis();
+		while (!match(predicate).isPresent()) {
+			Thread.sleep(20);
+			if (System.currentTimeMillis() - startTime > TIMEOUT) {
+				Assert.fail("Timeout elapsed while waiting for specific record.\n"
+						+ "Logged records:\n" + recordsToString());
+			}
+		}
+	}
+	
+	public void await(Level level, String message) throws InterruptedException {
+		long startTime = System.currentTimeMillis();
+		while (findRecord(level, message) == null) {
+			Thread.sleep(20);
+			if (System.currentTimeMillis() - startTime > TIMEOUT) {
+				Assert.fail("Timeout elapsed while waiting for " + level + ": \"" + message + "\"\n"
+						+ "Logged records:\n" + recordsToString());
+			}
+		}
+	}
+	
+	private String recordsToString() {
+		synchronized (records) {
+			if (records.isEmpty())
+				return "None";
+			return records.stream().map(r -> r.getLevel() + ": " + r.getMessage()).collect(Collectors.joining("\n"));
+		}
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/test/RemoteEndpointTest.java b/javatests/org/eclipse/lsp4j/jsonrpc/test/RemoteEndpointTest.java
new file mode 100644
index 0000000..f62d932
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/test/RemoteEndpointTest.java
@@ -0,0 +1,398 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+import java.util.logging.Level;
+
+import org.eclipse.lsp4j.jsonrpc.Endpoint;
+import org.eclipse.lsp4j.jsonrpc.JsonRpcException;
+import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
+import org.eclipse.lsp4j.jsonrpc.RemoteEndpoint;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.messages.Message;
+import org.eclipse.lsp4j.jsonrpc.messages.MessageIssue;
+import org.eclipse.lsp4j.jsonrpc.messages.NotificationMessage;
+import org.eclipse.lsp4j.jsonrpc.messages.RequestMessage;
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseError;
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseErrorCode;
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class RemoteEndpointTest {
+	
+	private static final long TIMEOUT = 2000;
+	
+	static class TestEndpoint implements Endpoint {
+		
+		List<NotificationMessage> notifications = new ArrayList<>();
+		Map<RequestMessage, CompletableFuture<Object>> requests = new LinkedHashMap<>();
+		
+		public void notify(String method, Object parameter) {
+			notifications.add(init(new NotificationMessage(), it -> {
+				it.setMethod(method);
+				it.setParams(parameter);
+			}));
+		}
+		
+		@Override
+		public CompletableFuture<Object> request(String method, Object parameter) {
+			CompletableFuture<Object> completableFuture = new CompletableFuture<Object>();
+			requests.put(init(new RequestMessage(), it -> {
+				it.setMethod(method);
+				it.setParams(parameter);
+			}), completableFuture);
+			return completableFuture;
+		}
+		
+	}
+	
+	static class TestMessageConsumer implements MessageConsumer {
+		
+		List<Message> messages = new ArrayList<>();
+
+		@Override
+		public void consume(Message message) {
+			messages.add(message);
+		}
+		
+	}
+	
+	static <T> T init(T value, Consumer<T> initializer) {
+		initializer.accept(value);
+		return value;
+	}
+	
+	@Test
+	public void testNotification() {
+		TestEndpoint endp = new TestEndpoint();
+		TestMessageConsumer consumer = new TestMessageConsumer();
+		RemoteEndpoint endpoint = new RemoteEndpoint(consumer, endp);
+		
+		endpoint.consume(init(new NotificationMessage(), it -> {
+			it.setMethod("foo");
+			it.setParams("myparam");
+		}));
+		
+		NotificationMessage notificationMessage = endp.notifications.get(0);
+		assertEquals("foo", notificationMessage.getMethod());
+		assertEquals("myparam", notificationMessage.getParams());
+		assertTrue(consumer.messages.isEmpty());
+	}
+	
+	@Test
+	public void testRequest1() {
+		TestEndpoint endp = new TestEndpoint();
+		TestMessageConsumer consumer = new TestMessageConsumer();
+		RemoteEndpoint endpoint = new RemoteEndpoint(consumer, endp);
+		
+		endpoint.consume(init(new RequestMessage(), it -> {
+			it.setId("1");
+			it.setMethod("foo");
+			it.setParams("myparam");
+		}));
+		
+		Entry<RequestMessage, CompletableFuture<Object>> entry = endp.requests.entrySet().iterator().next();
+		entry.getValue().complete("success");
+		assertEquals("foo", entry.getKey().getMethod());
+		assertEquals("myparam", entry.getKey().getParams());
+		ResponseMessage responseMessage = (ResponseMessage) consumer.messages.get(0);
+		assertEquals("success", responseMessage.getResult());
+		assertEquals(Either.forLeft("1"), responseMessage.getRawId());
+	}
+	
+	@Test
+	public void testRequest2() {
+		TestEndpoint endp = new TestEndpoint();
+		TestMessageConsumer consumer = new TestMessageConsumer();
+		RemoteEndpoint endpoint = new RemoteEndpoint(consumer, endp);
+		
+		endpoint.consume(init(new RequestMessage(), it -> {
+			it.setId(1);
+			it.setMethod("foo");
+			it.setParams("myparam");
+		}));
+		
+		Entry<RequestMessage, CompletableFuture<Object>> entry = endp.requests.entrySet().iterator().next();
+		entry.getValue().complete("success");
+		assertEquals("foo", entry.getKey().getMethod());
+		assertEquals("myparam", entry.getKey().getParams());
+		ResponseMessage responseMessage = (ResponseMessage) consumer.messages.get(0);
+		assertEquals("success", responseMessage.getResult());
+		assertEquals(Either.forRight(1), responseMessage.getRawId());
+	}
+	
+	@Test
+	public void testHandleRequestIssues() {
+		TestEndpoint endp = new TestEndpoint();
+		TestMessageConsumer consumer = new TestMessageConsumer();
+		RemoteEndpoint endpoint = new RemoteEndpoint(consumer, endp);
+		
+		endpoint.handle(init(new RequestMessage(), it -> {
+			it.setId("1");
+			it.setMethod("foo");
+			it.setParams("myparam");
+		}), Collections.singletonList(new MessageIssue("bar")));
+		
+		ResponseMessage responseMessage = (ResponseMessage) consumer.messages.get(0);
+		assertNotNull(responseMessage.getError());
+		assertEquals("bar", responseMessage.getError().getMessage());
+	}
+	
+	@Test
+	public void testCancellation() {
+		TestEndpoint endp = new TestEndpoint();
+		TestMessageConsumer consumer = new TestMessageConsumer();
+		RemoteEndpoint endpoint = new RemoteEndpoint(consumer, endp);
+		
+		endpoint.consume(init(new RequestMessage(), it -> {
+			it.setId("1");
+			it.setMethod("foo");
+			it.setParams("myparam");
+		}));
+		
+		Entry<RequestMessage, CompletableFuture<Object>> entry = endp.requests.entrySet().iterator().next();
+		entry.getValue().cancel(true);
+		ResponseMessage message = (ResponseMessage) consumer.messages.get(0);
+		assertNotNull(message);
+		ResponseError error = message.getError();
+		assertNotNull(error);
+		assertEquals(error.getCode(), ResponseErrorCode.RequestCancelled.getValue());
+		assertEquals(error.getMessage(), "The request (id: 1, method: 'foo') has been cancelled");
+	}
+	
+	@Test
+	public void testExceptionInEndpoint() {
+		LogMessageAccumulator logMessages = new LogMessageAccumulator();
+		try {
+			// Don't show the exception in the test execution log
+			logMessages.registerTo(RemoteEndpoint.class);
+			
+			TestEndpoint endp = new TestEndpoint() {
+				@Override
+				public CompletableFuture<Object> request(String method, Object parameter) {
+					throw new RuntimeException("BAAZ");
+				}
+			};
+			TestMessageConsumer consumer = new TestMessageConsumer();
+			RemoteEndpoint endpoint = new RemoteEndpoint(consumer, endp);
+			
+			endpoint.consume(init(new RequestMessage(), it -> {
+				it.setId("1");
+				it.setMethod("foo");
+				it.setParams("myparam");
+			}));
+			
+			ResponseMessage response = (ResponseMessage) consumer.messages.get(0);
+			assertEquals("Internal error.", response.getError().getMessage());
+			assertEquals(ResponseErrorCode.InternalError.getValue(), response.getError().getCode());
+			String exception = (String) response.getError().getData();
+			String expected = "java.lang.RuntimeException: BAAZ\n\tat org.eclipse.lsp4j.jsonrpc.test.RemoteEndpointTest";
+			assertEquals(expected, exception.replaceAll("\\r", "").substring(0, expected.length()));
+		} finally {
+			logMessages.unregister();
+		}
+	}
+	
+	@Test
+	public void testExceptionInConsumer() throws Exception {
+		TestEndpoint endp = new TestEndpoint();
+		MessageConsumer consumer = message -> {
+			throw new RuntimeException("BAAZ");
+		};
+		RemoteEndpoint endpoint = new RemoteEndpoint(consumer, endp);
+		
+		CompletableFuture<Object> future = endpoint.request("foo", "myparam");
+		future.whenComplete((result, exception) -> {
+			assertNull(result);
+			assertNotNull(exception);
+			assertEquals("BAAZ", exception.getMessage());
+		});
+		try {
+			future.get(TIMEOUT, TimeUnit.MILLISECONDS);
+			Assert.fail("Expected an ExecutionException.");
+		} catch (ExecutionException exception) {
+			assertEquals("java.lang.RuntimeException: BAAZ", exception.getMessage());
+		}
+	}
+	
+	@Test
+	public void testExceptionInCompletableFuture() throws Exception {
+		TestEndpoint endp = new TestEndpoint();
+		TestMessageConsumer consumer = new TestMessageConsumer();
+		RemoteEndpoint endpoint = new RemoteEndpoint(consumer, endp);
+		
+		CompletableFuture<Object> future = endpoint.request("foo", "myparam");
+		CompletableFuture<Void> chained = future.thenAccept(result -> {
+			throw new RuntimeException("BAAZ");
+		});
+		endpoint.consume(init(new ResponseMessage(), it -> {
+			it.setId("1");
+			it.setResult("Bar");
+		}));
+		try {
+			chained.get(TIMEOUT, TimeUnit.MILLISECONDS);
+			Assert.fail("Expected an ExecutionException.");
+		} catch (ExecutionException exception) {
+			assertEquals("java.lang.RuntimeException: BAAZ", exception.getMessage());
+		}
+	}
+	
+	@Test
+	public void testExceptionInOutputStream() throws Exception {
+		LogMessageAccumulator logMessages = new LogMessageAccumulator();
+		try {
+			logMessages.registerTo(RemoteEndpoint.class);
+			
+			TestEndpoint endp = new TestEndpoint();
+			MessageConsumer consumer = new MessageConsumer() {
+				@Override
+				public void consume(Message message) throws JsonRpcException {
+					throw new JsonRpcException(new SocketException("Permission denied: connect"));
+				}
+			};
+			RemoteEndpoint endpoint = new RemoteEndpoint(consumer, endp);
+			endpoint.notify("foo", null);
+			
+			logMessages.await(Level.WARNING, "Failed to send notification message.");
+		} finally {
+			logMessages.unregister();
+		}
+	}
+	
+	@Test
+	public void testOutputStreamClosed() throws Exception {
+		LogMessageAccumulator logMessages = new LogMessageAccumulator();
+		try {
+			logMessages.registerTo(RemoteEndpoint.class);
+			
+			TestEndpoint endp = new TestEndpoint();
+			MessageConsumer consumer = new MessageConsumer() {
+				@Override
+				public void consume(Message message) throws JsonRpcException {
+					throw new JsonRpcException(new SocketException("Socket closed"));
+				}
+			};
+			RemoteEndpoint endpoint = new RemoteEndpoint(consumer, endp);
+			endpoint.notify("foo", null);
+			
+			logMessages.await(Level.INFO, "Failed to send notification message.");
+		} finally {
+			logMessages.unregister();
+		}
+	}
+
+	@Test
+	public void testExceptionHandlerMisbehaving1() {
+		LogMessageAccumulator logMessages = new LogMessageAccumulator();
+		try {
+			// Don't show the exception in the test execution log
+			logMessages.registerTo(RemoteEndpoint.class);
+
+			TestEndpoint endp = new TestEndpoint() {
+				@Override
+				public CompletableFuture<Object> request(String method, Object parameter) {
+					throw new RuntimeException("BAAZ");
+				}
+			};
+			TestMessageConsumer consumer = new TestMessageConsumer();
+			// Misbehaving exception handler that returns null
+			RemoteEndpoint endpoint = new RemoteEndpoint(consumer, endp, (e) -> null);
+
+			endpoint.consume(init(new RequestMessage(), it -> {
+				it.setId("1");
+				it.setMethod("foo");
+				it.setParams("myparam");
+			}));
+
+			assertEquals("Check some response received", 1, consumer.messages.size());
+			ResponseMessage response = (ResponseMessage) consumer.messages.get(0);
+			assertEquals(ResponseErrorCode.InternalError.getValue(), response.getError().getCode());
+		} finally {
+			logMessages.unregister();
+		}
+	}
+
+	static class TestMessageConsumer2 implements MessageConsumer {
+
+		boolean sentException = false;
+		List<Message> messages = new ArrayList<>();
+
+		@Override
+		public void consume(Message message) {
+			if (sentException) {
+				messages.add(message);
+			} else {
+				// throw an exception only for the first message
+				sentException = true;
+				throw new RuntimeException("Exception in consumer");
+			}
+		}
+
+	}
+	
+	@Test
+	public void testExceptionHandlerMisbehaving2() throws Exception {
+		LogMessageAccumulator logMessages = new LogMessageAccumulator();
+		try {
+			// Don't show the exception in the test execution log
+			logMessages.registerTo(RemoteEndpoint.class);
+
+			TestEndpoint endp = new TestEndpoint() {
+				@Override
+				public CompletableFuture<Object> request(String method, Object parameter) {
+					return CompletableFuture.supplyAsync(() -> "baz");
+				}
+			};
+			TestMessageConsumer2 consumer = new TestMessageConsumer2();
+			// Misbehaving exception handler that returns null
+			RemoteEndpoint endpoint = new RemoteEndpoint(consumer, endp, (e) -> null);
+
+			endpoint.consume(init(new RequestMessage(), it -> {
+				it.setId("1");
+				it.setMethod("foo");
+				it.setParams("myparam");
+			}));
+
+			long timeout = System.currentTimeMillis() + TIMEOUT;
+			while (consumer.messages.isEmpty()) {
+				Thread.sleep(20);
+				if (System.currentTimeMillis() > timeout) {
+					fail("Timedout waiting for messages");
+				}
+			}
+			assertEquals("Check some response received", 1, consumer.messages.size());
+			ResponseMessage response = (ResponseMessage) consumer.messages.get(0);
+			assertNotNull("Check response has error", response.getError());
+			assertEquals(ResponseErrorCode.InternalError.getValue(), response.getError().getCode());
+		} finally {
+			logMessages.unregister();
+		}
+	}
+}
\ No newline at end of file
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/test/TracingMessageConsumerTest.java b/javatests/org/eclipse/lsp4j/jsonrpc/test/TracingMessageConsumerTest.java
new file mode 100644
index 0000000..a514532
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/test/TracingMessageConsumerTest.java
@@ -0,0 +1,265 @@
+/******************************************************************************
+ * Copyright (c) 2016-2019 TypeFox and others.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.test;
+
+import org.eclipse.lsp4j.jsonrpc.*;
+import org.eclipse.lsp4j.jsonrpc.TracingMessageConsumer.RequestMetadata;
+import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
+import org.eclipse.lsp4j.jsonrpc.json.StreamMessageConsumer;
+import org.eclipse.lsp4j.jsonrpc.messages.*;
+import org.junit.Test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.time.Clock;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+
+import static java.util.Collections.emptyMap;
+import static org.junit.Assert.assertEquals;
+
+public class TracingMessageConsumerTest {
+	private static final RemoteEndpoint TEST_REMOTE_ENDPOINT = new EmptyRemoteEndpoint();
+	private static final StreamMessageConsumer TEST_STREAM_MESSAGE_CONSUMER =
+			new StreamMessageConsumer(
+					new ByteArrayOutputStream(), new MessageJsonHandler(emptyMap()));
+	private static final Clock TEST_CLOCK_1 =
+			Clock.fixed(Instant.parse("2019-06-26T22:07:30.00Z"), ZoneId.of("America/New_York"));
+	private static final Clock TEST_CLOCK_2 =
+			Clock.fixed(Instant.parse("2019-06-26T22:07:30.10Z"), ZoneId.of("America/New_York"));
+
+	@Test
+	public void testReceivedRequest() {
+		StringWriter stringWriter = new StringWriter();
+		PrintWriter printWriter = new PrintWriter(stringWriter);
+
+		TracingMessageConsumer consumer =
+				new TracingMessageConsumer(
+						TEST_REMOTE_ENDPOINT, new HashMap<>(), new HashMap<>(), printWriter, TEST_CLOCK_1, Locale.US);
+
+		RequestMessage message = new RequestMessage();
+		message.setId("1");
+		message.setMethod("foo");
+		message.setParams("bar");
+
+		consumer.consume(message);
+
+		String actualTrace = stringWriter.toString();
+		String expectedTrace = "" +
+				"[Trace - 06:07:30 PM] Received request 'foo - (1)'\n" +
+				"Params: \"bar\"\n" +
+				"\n" +
+				"\n";
+
+		assertEquals(expectedTrace, actualTrace);
+	}
+
+	@Test
+	public void testReceivedResultResponse() {
+		StringWriter stringWriter = new StringWriter();
+		PrintWriter printWriter = new PrintWriter(stringWriter);
+
+		Map<String, RequestMetadata> sentRequests = new HashMap<>();
+		sentRequests.put("1", new RequestMetadata("foo", TEST_CLOCK_1.instant()));
+
+		TracingMessageConsumer consumer =
+				new TracingMessageConsumer(
+						TEST_REMOTE_ENDPOINT, sentRequests, new HashMap<>(), printWriter, TEST_CLOCK_2, Locale.US);
+
+		ResponseMessage message = new ResponseMessage();
+		message.setId("1");
+		message.setResult("bar");
+
+		consumer.consume(message);
+
+		String actualTrace = stringWriter.toString();
+		String expectedTrace = "" +
+				"[Trace - 06:07:30 PM] Received response 'foo - (1)' in 100ms\n" +
+				"Result: \"bar\"\n" +
+				"Error: null\n" +
+				"\n" +
+				"\n";
+
+		assertEquals(expectedTrace, actualTrace);
+	}
+
+	@Test
+	public void testReceivedErrorResponse() {
+		StringWriter stringWriter = new StringWriter();
+		PrintWriter printWriter = new PrintWriter(stringWriter);
+
+		Map<String, RequestMetadata> sentRequests = new HashMap<>();
+		sentRequests.put("1", new RequestMetadata("foo", TEST_CLOCK_1.instant()));
+
+		TracingMessageConsumer consumer =
+				new TracingMessageConsumer(
+						TEST_REMOTE_ENDPOINT, sentRequests, new HashMap<>(), printWriter, TEST_CLOCK_2, Locale.US);
+
+		ResponseMessage message = new ResponseMessage();
+		message.setId("1");
+		message.setError(new ResponseError(-32600, "bar", null));
+
+		consumer.consume(message);
+
+		String actualTrace = stringWriter.toString();
+		String expectedTrace = "" +
+				"[Trace - 06:07:30 PM] Received response 'foo - (1)' in 100ms\n" +
+				"Result: null\n" +
+				"Error: {\n" +
+				"  \"code\": -32600,\n" +
+				"  \"message\": \"bar\"\n" +
+				"}\n" +
+				"\n" +
+				"\n";
+
+		assertEquals(expectedTrace, actualTrace);
+	}
+
+	@Test
+	public void testReceivedNotification() {
+		StringWriter stringWriter = new StringWriter();
+		PrintWriter printWriter = new PrintWriter(stringWriter);
+
+		TracingMessageConsumer consumer =
+				new TracingMessageConsumer(
+						TEST_REMOTE_ENDPOINT, new HashMap<>(), new HashMap<>(), printWriter, TEST_CLOCK_1, Locale.US);
+
+		NotificationMessage message = new NotificationMessage();
+		message.setMethod("foo");
+		message.setParams("bar");
+
+		consumer.consume(message);
+
+		String actualTrace = stringWriter.toString();
+		String expectedTrace = "" +
+				"[Trace - 06:07:30 PM] Received notification 'foo'\n" +
+				"Params: \"bar\"\n" +
+				"\n" +
+				"\n";
+
+		assertEquals(expectedTrace, actualTrace);
+	}
+
+	@Test
+	public void testSendingRequest() {
+		StringWriter stringWriter = new StringWriter();
+		PrintWriter printWriter = new PrintWriter(stringWriter);
+
+		TracingMessageConsumer consumer =
+				new TracingMessageConsumer(
+						TEST_STREAM_MESSAGE_CONSUMER, new HashMap<>(), new HashMap<>(), printWriter, TEST_CLOCK_1, Locale.US);
+
+		RequestMessage message = new RequestMessage();
+		message.setId("1");
+		message.setMethod("foo");
+		message.setParams("bar");
+
+		consumer.consume(message);
+
+		String actualTrace = stringWriter.toString();
+		String expectedTrace = "" +
+				"[Trace - 06:07:30 PM] Sending request 'foo - (1)'\n" +
+				"Params: \"bar\"\n" +
+				"\n" +
+				"\n";
+
+		assertEquals(expectedTrace, actualTrace);
+	}
+
+	@Test
+	public void testSendingResponse() {
+		StringWriter stringWriter = new StringWriter();
+		PrintWriter printWriter = new PrintWriter(stringWriter);
+
+		Map<String, RequestMetadata> receivedRequests = new HashMap<>();
+		receivedRequests.put("1", new RequestMetadata("foo", TEST_CLOCK_1.instant()));
+
+		TracingMessageConsumer consumer =
+				new TracingMessageConsumer(
+						TEST_STREAM_MESSAGE_CONSUMER, new HashMap<>(), receivedRequests, printWriter, TEST_CLOCK_2, Locale.US);
+
+		ResponseMessage message = new ResponseMessage();
+		message.setId("1");
+		message.setResult("bar");
+
+		consumer.consume(message);
+
+		String actualTrace = stringWriter.toString();
+		String expectedTrace = "" +
+				"[Trace - 06:07:30 PM] Sending response 'foo - (1)'. Processing request took 100ms\n" +
+				"Result: \"bar\"\n" +
+				"\n" +
+				"\n";
+
+		assertEquals(expectedTrace, actualTrace);
+	}
+
+	@Test
+	public void testSendingNotification() {
+		StringWriter stringWriter = new StringWriter();
+		PrintWriter printWriter = new PrintWriter(stringWriter);
+
+		TracingMessageConsumer consumer =
+				new TracingMessageConsumer(
+						TEST_STREAM_MESSAGE_CONSUMER, emptyMap(), emptyMap(), printWriter, TEST_CLOCK_1, Locale.US);
+
+		NotificationMessage message = new NotificationMessage();
+		message.setMethod("foo");
+		message.setParams("bar");
+
+		consumer.consume(message);
+
+		String actualTrace = stringWriter.toString();
+		String expectedTrace = "" +
+				"[Trace - 06:07:30 PM] Sending notification 'foo'\n" +
+				"Params: \"bar\"\n" +
+				"\n" +
+				"\n";
+
+		assertEquals(expectedTrace, actualTrace);
+	}
+}
+
+class EmptyRemoteEndpoint extends RemoteEndpoint {
+	EmptyRemoteEndpoint() {
+		super(new EmptyMessageConsumer(), new EmptyEndpoint());
+	}
+
+	@Override
+	protected void handleResponse(ResponseMessage responseMessage) {
+		// no-op
+	}
+}
+
+class EmptyMessageConsumer implements MessageConsumer {
+	@Override
+	public void consume(Message message) throws MessageIssueException, JsonRpcException {
+		// no-op
+	}
+}
+
+class EmptyEndpoint implements Endpoint {
+	@Override
+	public CompletableFuture<?> request(String method, Object parameter) {
+		return CompletableFuture.completedFuture(new Object());
+	}
+
+	@Override
+	public void notify(String method, Object parameter) {
+		// no-op
+	}
+}
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/test/annotations/EndpointsTest.java b/javatests/org/eclipse/lsp4j/jsonrpc/test/annotations/EndpointsTest.java
new file mode 100644
index 0000000..bf6e8a9
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/test/annotations/EndpointsTest.java
@@ -0,0 +1,242 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.test.annotations;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+
+import org.eclipse.lsp4j.jsonrpc.Endpoint;
+import org.eclipse.lsp4j.jsonrpc.json.JsonRpcMethod;
+import org.eclipse.lsp4j.jsonrpc.services.GenericEndpoint;
+import org.eclipse.lsp4j.jsonrpc.services.JsonDelegate;
+import org.eclipse.lsp4j.jsonrpc.services.JsonNotification;
+import org.eclipse.lsp4j.jsonrpc.services.JsonRequest;
+import org.eclipse.lsp4j.jsonrpc.services.JsonSegment;
+import org.eclipse.lsp4j.jsonrpc.services.ServiceEndpoints;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class EndpointsTest {
+	
+	private static final long TIMEOUT = 2000;
+	
+	@JsonSegment("foo")
+	public static interface Foo {
+		@JsonRequest
+		public CompletableFuture<String> doStuff(String arg);
+		
+		@JsonNotification
+		public void myNotification(String someArg);
+		
+		@JsonDelegate
+		public Delegated getDelegate();
+	}
+	
+	public static interface Delegated {
+		
+		@JsonNotification("hubba")
+		public void myNotification(String someArg);
+	}
+	
+	@JsonSegment("bar")
+	public static interface Bar {
+		@JsonRequest
+		public CompletableFuture<String> doStuff2(String arg, Integer arg2);
+		
+		@JsonNotification
+		public void myNotification2(String someArg, Integer someArg2);
+		
+		@JsonDelegate
+		public BarDelegated getDelegate2();
+	}
+	
+	public static interface BarDelegated {
+		
+		@JsonNotification("hubba")
+		public void myNotification(String someArg, Integer someArg2);
+	}
+
+	@Test public void testProxy_01() throws Exception {
+		Endpoint endpoint = new Endpoint() {
+			
+			@Override
+			public CompletableFuture<?> request(String method, Object parameter) {
+				assertEquals("foo/doStuff", method);
+				assertEquals("param", parameter.toString());
+				return CompletableFuture.completedFuture("result");
+			}
+			
+			@Override
+			public void notify(String method, Object parameter) {
+				assertEquals("foo/myNotification", method);
+				assertEquals("notificationParam", parameter.toString());
+			}
+		};
+		Foo foo = ServiceEndpoints.toServiceObject(endpoint, Foo.class);
+		foo.myNotification("notificationParam");
+		assertEquals("result", foo.doStuff("param").get(TIMEOUT, TimeUnit.MILLISECONDS));
+	}
+	
+	@Test public void testProxy_02() throws Exception {
+		Endpoint endpoint = new Endpoint() {
+			
+			@Override
+			public CompletableFuture<?> request(String method, Object parameter) {
+				assertEquals("bar/doStuff2", method);
+				assertEquals("[param, 2]", parameter.toString());
+				return CompletableFuture.completedFuture("result");
+			}
+			
+			@Override
+			public void notify(String method, Object parameter) {
+				assertEquals("bar/myNotification2", method);
+				assertEquals("[notificationParam, 1]", parameter.toString());
+			}
+		};
+		Bar bar = ServiceEndpoints.toServiceObject(endpoint, Bar.class);
+		bar.myNotification2("notificationParam", 1);
+		assertEquals("result", bar.doStuff2("param", 2).get(TIMEOUT, TimeUnit.MILLISECONDS));
+	}
+	
+	@Test public void testBackAndForth() throws Exception {
+		Endpoint endpoint = new Endpoint() {
+			@Override
+			public CompletableFuture<?> request(String method, Object parameter) {
+				assertEquals("foo/doStuff", method);
+				assertEquals("param", parameter.toString());
+				return CompletableFuture.completedFuture("result");
+			}
+			
+			@Override
+			public void notify(String method, Object parameter) {
+				assertEquals("foo/myNotification", method);
+				assertEquals("notificationParam", parameter.toString());
+			}
+		};
+		Foo intermediateFoo = ServiceEndpoints.toServiceObject(endpoint, Foo.class);
+		Endpoint secondEndpoint = ServiceEndpoints.toEndpoint(intermediateFoo); 
+		Foo foo = ServiceEndpoints.toServiceObject(secondEndpoint, Foo.class);
+		foo.myNotification("notificationParam");
+		assertEquals("result", foo.doStuff("param").get(TIMEOUT, TimeUnit.MILLISECONDS));
+	}
+	
+	@Test public void testMultipleInterfaces() throws Exception {
+		final Map<String, Object> requests = new HashMap<>();
+		final Map<String, Object> notifications = new HashMap<>();
+		Endpoint endpoint = new Endpoint() {
+			@Override
+			public CompletableFuture<?> request(String method, Object parameter) {
+				requests.put(method, parameter);
+				switch (method) {
+				case "foo/doStuff":
+					assertEquals("paramFoo", parameter);
+					return CompletableFuture.completedFuture("resultFoo");
+				case "bar/doStuff2":
+					assertEquals(Arrays.asList("paramBar", 77), parameter);
+					return CompletableFuture.completedFuture("resultBar");
+				default:
+					Assert.fail("Unexpected method: " + method);
+					return null;
+				}
+			}
+			
+			@Override
+			public void notify(String method, Object parameter) {
+				notifications.put(method, parameter);
+			}
+		};
+		ClassLoader classLoader = getClass().getClassLoader();
+		Object proxy = ServiceEndpoints.toServiceObject(endpoint, Arrays.asList(Foo.class, Bar.class), classLoader);
+		Foo foo = (Foo) proxy;
+		foo.myNotification("notificationParamFoo");
+		assertEquals("resultFoo", foo.doStuff("paramFoo").get(TIMEOUT, TimeUnit.MILLISECONDS));
+		Bar bar = (Bar) proxy;
+		bar.myNotification2("notificationParamBar", 42);
+		assertEquals("resultBar", bar.doStuff2("paramBar", 77).get(TIMEOUT, TimeUnit.MILLISECONDS));
+		
+		assertEquals(2, requests.size());
+		assertEquals(2, notifications.size());
+		assertEquals("notificationParamFoo", notifications.get("foo/myNotification"));
+		assertEquals(Arrays.asList("notificationParamBar", 42), notifications.get("bar/myNotification2"));
+	}
+	
+	@Test public void testRpcMethods_01() {
+		Map<String, JsonRpcMethod> methods = ServiceEndpoints.getSupportedMethods(Foo.class);
+		
+		assertEquals("foo/doStuff", methods.get("foo/doStuff").getMethodName());
+		assertEquals(String.class, methods.get("foo/doStuff").getParameterTypes()[0]);
+		assertFalse(methods.get("foo/doStuff").isNotification());
+		
+		assertEquals("foo/myNotification", methods.get("foo/myNotification").getMethodName());
+		assertEquals(String.class, methods.get("foo/myNotification").getParameterTypes()[0]);
+		assertTrue(methods.get("foo/myNotification").isNotification());
+		
+		assertEquals("hubba", methods.get("hubba").getMethodName());
+		assertEquals(String.class, methods.get("hubba").getParameterTypes()[0]);
+		assertTrue(methods.get("hubba").isNotification());
+	}
+	
+	@Test public void testRpcMethods_02() {
+		Map<String, JsonRpcMethod> methods = ServiceEndpoints.getSupportedMethods(Bar.class);
+		
+		final JsonRpcMethod requestMethod = methods.get("bar/doStuff2");
+		assertEquals("bar/doStuff2", requestMethod.getMethodName());
+		assertEquals(2, requestMethod.getParameterTypes().length);
+		assertEquals(String.class, requestMethod.getParameterTypes()[0]);
+		assertEquals(Integer.class, requestMethod.getParameterTypes()[1]);
+		assertFalse(requestMethod.isNotification());
+		
+		final JsonRpcMethod notificationMethod = methods.get("bar/myNotification2");
+		assertEquals("bar/myNotification2", notificationMethod.getMethodName());
+		assertEquals(2, notificationMethod.getParameterTypes().length);
+		assertEquals(String.class, notificationMethod.getParameterTypes()[0]);
+		assertEquals(Integer.class, notificationMethod.getParameterTypes()[1]);
+		assertTrue(notificationMethod.isNotification());
+		
+		final JsonRpcMethod delegateMethod = methods.get("hubba");
+		assertEquals("hubba", delegateMethod.getMethodName());
+		assertEquals(2, delegateMethod.getParameterTypes().length);
+		assertEquals(String.class, delegateMethod.getParameterTypes()[0]);
+		assertEquals(Integer.class, delegateMethod.getParameterTypes()[1]);
+		assertTrue(delegateMethod.isNotification());
+	}
+	
+	@JsonSegment("consumer")
+	public static interface StringConsumer extends Consumer<String> {
+		@JsonNotification
+		@Override
+		void accept(String message);
+	}
+	
+	@Test public void testIssue106() {
+		Foo foo = ServiceEndpoints.toServiceObject(new GenericEndpoint(new Object()), Foo.class);
+		assertEquals(foo, foo);
+	}
+	
+	@Test public void testIssue107() {
+		Map<String, JsonRpcMethod> methods = ServiceEndpoints.getSupportedMethods(StringConsumer.class);
+		final JsonRpcMethod method = methods.get("consumer/accept");
+		assertEquals("consumer/accept", method.getMethodName());
+		assertEquals(1, method.getParameterTypes().length);
+		assertEquals(String.class, method.getParameterTypes()[0]);
+		assertTrue(method.isNotification());
+	}
+	
+}
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/test/annotations/impl/GenericEndpointTest.java b/javatests/org/eclipse/lsp4j/jsonrpc/test/annotations/impl/GenericEndpointTest.java
new file mode 100644
index 0000000..b8bdee0
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/test/annotations/impl/GenericEndpointTest.java
@@ -0,0 +1,285 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.test.annotations.impl;
+
+import java.util.Arrays;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Predicate;
+import java.util.logging.Level;
+
+import org.eclipse.lsp4j.jsonrpc.services.GenericEndpoint;
+import org.eclipse.lsp4j.jsonrpc.services.JsonDelegate;
+import org.eclipse.lsp4j.jsonrpc.services.JsonNotification;
+import org.eclipse.lsp4j.jsonrpc.services.JsonRequest;
+import org.eclipse.lsp4j.jsonrpc.services.JsonSegment;
+import org.eclipse.lsp4j.jsonrpc.test.LogMessageAccumulator;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class GenericEndpointTest {
+
+	public static class Foo implements MyIf, OtherThing {
+
+		public int calls = 0;
+
+		@Override
+		public void myNotification() {
+			calls++;
+		}
+
+		@Override
+		public OtherThing doDelegate() {
+			return this;
+		}
+
+	}
+	
+	public static class Bar {
+		
+		public int calls = 0;
+		
+		@JsonNotification
+		public void barrr() {
+			calls++;
+		}
+		
+	}
+
+	public static interface MyIf {
+
+		@JsonNotification
+		public void myNotification();
+
+		@JsonDelegate
+		public OtherThing doDelegate();
+	}
+
+	@JsonSegment("other")
+	public static interface OtherThing {
+
+		@JsonNotification
+		public void myNotification();
+	}
+
+	@Test
+	public void testSimple() {
+		Foo foo = new Foo();
+		GenericEndpoint endpoint = new GenericEndpoint(foo);
+		endpoint.notify("myNotification", null);
+		endpoint.notify("other/myNotification", null);
+
+		Assert.assertEquals(2, foo.calls);
+	}
+	
+	@Test
+	public void testMultiServices() {
+		Foo foo = new Foo();
+		Bar bar = new Bar();
+		GenericEndpoint endpoint = new GenericEndpoint(Arrays.asList(foo, bar));
+		endpoint.notify("myNotification", null);
+		endpoint.notify("barrr", null);
+		endpoint.notify("other/myNotification", null);
+		
+		Assert.assertEquals(2, foo.calls);
+		Assert.assertEquals(1, bar.calls);
+	}
+
+	@Test
+	public void testUnexpectedParams() {
+		LogMessageAccumulator logMessages = new LogMessageAccumulator();
+		try {
+			logMessages.registerTo(GenericEndpoint.class);
+			
+			Foo foo = new Foo();
+			GenericEndpoint endpoint = new GenericEndpoint(foo);
+			Assert.assertEquals(0, foo.calls);
+	
+			endpoint.notify("myNotification", new Object());
+			Assert.assertEquals(1, foo.calls);
+		} finally {
+			logMessages.unregister();
+		}
+	}
+	
+	@Test
+	public void testZeroParams_01() throws Exception {
+		testZeroParams("foo", m -> m.contains("Unexpected params 'foo'"));
+	}
+	
+	@Test
+	public void testZeroParams_02() throws Exception {
+		testZeroParams(null);
+	}
+	
+	@Test
+	public void testZeroParams_03() throws Exception {
+		testZeroParams(Arrays.asList("foo"), m -> m.contains("Unexpected params '[foo]'"));
+	}
+	
+	@Test
+	public void testZeroParams_04() throws Exception {
+		testZeroParams(Arrays.asList("foo", "bar"), m -> m.contains("Unexpected params '[foo, bar]'"));
+	}
+	
+	protected void testZeroParams(Object params) throws Exception {
+		testZeroParams(params, null);
+	}
+
+	protected void testZeroParams(Object params, Predicate<String> predicate) throws Exception {
+		LogMessageAccumulator logMessages = null;
+		try {
+			if (predicate != null) {
+				logMessages = new LogMessageAccumulator();
+				logMessages.registerTo(GenericEndpoint.class);
+			}
+			GenericEndpoint endpoint = new GenericEndpoint(new Object() {
+
+				@JsonNotification
+				public void myNotification() {
+				}
+
+			});
+		
+			endpoint.notify("myNotification", params);
+
+			if (predicate != null) {
+				logMessages.await(r -> Level.WARNING == r.getLevel() && predicate.test(r.getMessage()));
+			}
+		} finally {
+			if (logMessages != null) {
+				logMessages.unregister();
+			}
+		}
+	}
+	
+	@Test
+	public void testSingleParams_01() throws Exception {
+		testSingleParams("foo", "foo");
+	}
+	
+	@Test
+	public void testSingleParams_02() throws Exception {
+		testSingleParams(null, null);
+	}
+	
+	@Test
+	public void testSingleParams_03() throws Exception {
+		testSingleParams(Arrays.asList("foo"), "foo");
+	}
+	
+	@Test
+	public void testSingleParams_04() throws Exception {
+		testSingleParams(Arrays.asList("foo", "bar"), "foo", m -> m.contains("Unexpected params 'bar'"));
+	}
+	
+	protected void testSingleParams(Object params, String expectedString) throws Exception {
+		this.testSingleParams(params, expectedString, null);
+	}
+
+	protected void testSingleParams(Object params, String expectedString, Predicate<String> predicate) throws Exception {
+		LogMessageAccumulator logMessages = null;
+		try {
+			if (predicate != null) {
+				logMessages = new LogMessageAccumulator();
+				logMessages.registerTo(GenericEndpoint.class);
+			}
+			GenericEndpoint endpoint = new GenericEndpoint(new Object() {
+
+				@JsonRequest
+				public CompletableFuture<String> getStringValue(String stringValue) {
+					return CompletableFuture.completedFuture(stringValue);
+				}
+
+			});
+
+			Assert.assertEquals(expectedString, endpoint.request("getStringValue", params).get());
+
+			if (predicate != null) {
+				logMessages.await(r -> Level.WARNING == r.getLevel() && predicate.test(r.getMessage()));
+			}
+		} finally {
+			if (logMessages != null) {
+				logMessages.unregister();
+			}
+		}
+	}
+
+	@Test
+	public void testMultiParams_01() throws Exception {
+		testMultiParams(Arrays.asList("foo", 1), "foo", 1);
+	}
+
+	@Test
+	public void testMultiParams_02() throws Exception {
+		testMultiParams(Arrays.asList("foo"), "foo", null);
+	}
+
+	@Test
+	public void testMultiParams_03() throws Exception {
+		testMultiParams(Arrays.asList("foo", 1, "bar", 2), "foo", 1, m -> m.contains("Unexpected params 'bar', '2'"));
+	}
+
+	@Test
+	public void testMultiParams_04() throws Exception {
+		testMultiParams("foo", "foo", null);
+	}
+	
+	protected void testMultiParams(Object params, String expectedString, Integer expectedInt) throws Exception {
+		testMultiParams(params, expectedString, expectedInt, null);
+	}
+
+	protected void testMultiParams(Object params, String expectedString, Integer expectedInt, Predicate<String> predicate) throws Exception {
+		LogMessageAccumulator logMessages = null;
+		try {
+			if (predicate != null) {
+				logMessages = new LogMessageAccumulator();
+				logMessages.registerTo(GenericEndpoint.class);
+			}
+
+			GenericEndpoint endpoint = new GenericEndpoint(new Object() {
+
+				String stringValue;
+				Integer intValue;
+
+				@JsonRequest
+				public CompletableFuture<String> getStringValue() {
+					return CompletableFuture.completedFuture(stringValue);
+				}
+
+				@JsonRequest
+				public CompletableFuture<Integer> getIntValue() {
+					return CompletableFuture.completedFuture(intValue);
+				}
+
+				@JsonNotification
+				public void myNotification(String stringValue, Integer intValue) {
+					this.stringValue = stringValue;
+					this.intValue = intValue;
+				}
+
+			});
+			endpoint.notify("myNotification", params);
+
+			if (predicate != null) {
+				logMessages.await(r -> Level.WARNING == r.getLevel() && predicate.test(r.getMessage()));
+			}
+
+			Assert.assertEquals(expectedString, endpoint.request("getStringValue", null).get());
+			Assert.assertEquals(expectedInt, endpoint.request("getIntValue", null).get());
+		} finally {
+			if (logMessages != null) {
+				logMessages.unregister();
+			}
+		}
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/test/json/CollectionTest.java b/javatests/org/eclipse/lsp4j/jsonrpc/test/json/CollectionTest.java
new file mode 100644
index 0000000..23a7f9e
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/test/json/CollectionTest.java
@@ -0,0 +1,92 @@
+/******************************************************************************
+ * Copyright (c) 2017-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.test.json;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+import org.eclipse.lsp4j.jsonrpc.json.adapters.CollectionTypeAdapter;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+
+public class CollectionTest {
+
+	protected Gson createGson() {
+		return new GsonBuilder().registerTypeAdapterFactory(new CollectionTypeAdapter.Factory()).create();
+	}
+
+	protected void assertSerialize(Object object, String expected) {
+		Gson gson = createGson();
+		String actual = gson.toJson(object);
+		Assert.assertEquals(expected, actual);
+	}
+
+	protected void assertParse(Object expected, String string) {
+		Gson gson = createGson();
+		Object actual = gson.fromJson(string, expected.getClass());
+		Assert.assertEquals(expected, actual);
+	}
+
+	@Test
+	public void testSerializeList() {
+		MyObjectA object = new MyObjectA();
+		object.myProperty = Arrays.asList("foo", "bar");
+		assertSerialize(object, "{\"myProperty\":[\"foo\",\"bar\"]}");
+	}
+
+	@Test
+	public void testSerializeNull() {
+		MyObjectA object = new MyObjectA();
+		object.myProperty = null;
+		object.otherProperty = "ok";
+		assertParse(object, "{\"otherProperty\":\"ok\"}");
+	}
+
+	@Test
+	public void testParseList() {
+		MyObjectA object = new MyObjectA();
+		object.myProperty = Arrays.asList("foo", "bar");
+		assertParse(object, "{\"myProperty\":[\"foo\",\"bar\"]}");
+	}
+
+	@Test
+	public void testParseNull() {
+		MyObjectA object = new MyObjectA();
+		object.myProperty = null;
+		object.otherProperty = "ok";
+		assertParse(object, "{\"myProperty\":null, \"otherProperty\": \"ok\"}");
+	}
+
+	protected static class MyObjectA {
+		public List<String> myProperty;
+		public String otherProperty;
+
+		@Override
+		public boolean equals(Object obj) {
+			if (obj instanceof MyObjectA) {
+				MyObjectA other = (MyObjectA) obj;
+				return Objects.equals(this.myProperty, other.myProperty) && Objects.equals(this.otherProperty, otherProperty);
+			}
+			return false;
+		}
+
+		@Override
+		public int hashCode() {
+			return Objects.hash(this.myProperty, this.otherProperty);
+		}
+	}
+}
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/test/json/EitherTest.java b/javatests/org/eclipse/lsp4j/jsonrpc/test/json/EitherTest.java
new file mode 100644
index 0000000..6c12780
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/test/json/EitherTest.java
@@ -0,0 +1,267 @@
+/******************************************************************************
+ * Copyright (c) 2017 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.test.json;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Objects;
+import java.util.function.Function;
+
+import org.eclipse.lsp4j.jsonrpc.json.adapters.EitherTypeAdapter;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.messages.Either3;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonObject;
+
+
+public class EitherTest {
+
+	protected Gson createGson() {
+		return new GsonBuilder().registerTypeAdapterFactory(new EitherTypeAdapter.Factory()).create();
+	}
+
+	protected void assertSerialize(String expected, Object object) {
+		Gson gson = createGson();
+		String actual = gson.toJson(object);
+		Assert.assertEquals(expected, actual);
+	}
+
+	protected void assertParse(Object expected, String string) {
+		Gson gson = createGson();
+		Object actual = gson.fromJson(string, expected.getClass());
+		Assert.assertEquals(expected, actual);
+	}
+
+	@Test
+	public void testSerializeEither() {
+		MyObjectA object = new MyObjectA();
+		object.myProperty = Either.forRight(7);
+		assertSerialize("{\"myProperty\":7}", object);
+	}
+
+	@Test
+	public void testSerializeNull() {
+		MyObjectA object = new MyObjectA();
+		object.myProperty = null;
+		object.otherProperty = "ok";
+		assertSerialize("{\"otherProperty\":\"ok\"}", object);
+	}
+
+	@Test
+	public void testParseEither() {
+		MyObjectA object = new MyObjectA();
+		object.myProperty = Either.forRight(7);
+		assertParse(object, "{\"myProperty\":7}");
+	}
+
+	@Test
+	public void testParseNull() {
+		MyObjectA object = new MyObjectA();
+		object.myProperty = null;
+		object.otherProperty = "ok";
+		assertParse(object, "{\"myProperty\":null, \"otherProperty\": \"ok\"}");
+	}
+	
+	@Test
+	public void testEqualsForNull() {
+		Either<Object, Object> either1 = Either.forLeft(null);
+		Either<Object, Object> either2 = Either.forLeft(null);
+
+		assertTrue(either1.equals(either2));
+	}
+
+	@Test
+	public void testLeftEqualsNull() {
+		Either<Object, String> either1 = Either.forRight("Testing");
+		Either<Object, String> either2 = Either.forRight("Testing");
+
+		assertTrue(either1.equals(either2));
+	}
+
+	@Test
+	public void testRightEqualsNull() {
+		Either<Object, String> either1 = Either.forLeft("Testing");
+		Either<Object, String> either2 = Either.forLeft("Testing");
+
+		assertTrue(either1.equals(either2));
+	}
+
+	@Test
+	public void testEqualsFalseWithNonNull() {
+		Either<Object, String> either1 = Either.forLeft("Testing");
+		Either<Object, String> either2 = Either.forRight("Testing");
+
+		assertFalse(either1.equals(either2));
+	}
+
+	@Test
+	public void testMap() {
+		Either<char[], String> either = Either.forLeft(new char[] { 'f', 'o', 'o' });
+		assertEquals("foo", either.map(
+				String::new,
+				String::toUpperCase));
+		either = Either.forRight("bar");
+		assertEquals("BAR", either.map(
+				String::new,
+				String::toUpperCase));
+	}
+
+	@Test
+	public void testMapEither3() {
+		Either3<String, Integer, Boolean> either3;
+		Function<String, String> mapFirst = s -> s.toUpperCase();
+		Function<Integer, String> mapSecond = x -> x.toString();
+		Function<Boolean, String> mapThird = b -> b.toString();
+
+		either3 = Either3.forFirst("abc");
+		assertEquals("ABC", either3.map(mapFirst, mapSecond, mapThird));
+
+		either3 = Either3.forSecond(123);
+		assertEquals("123", either3.map(mapFirst, mapSecond, mapThird));
+
+		either3 = Either3.forThird(Boolean.TRUE);
+		assertEquals("true", either3.map(mapFirst, mapSecond, mapThird));
+	}
+
+	protected static class MyObjectA {
+		public Either<String, Integer> myProperty;
+		public String otherProperty;
+
+		@Override
+		public boolean equals(Object obj) {
+			if (obj instanceof MyObjectA) {
+				MyObjectA other = (MyObjectA) obj;
+				return Objects.equals(this.myProperty, other.myProperty) && Objects.equals(this.otherProperty, otherProperty);
+			}
+			return false;
+		}
+
+		@Override
+		public int hashCode() {
+			return Objects.hash(this.myProperty, this.otherProperty);
+		}
+	}
+
+	@Test
+	public void testSerializeEither3() {
+		MyObjectB object = new MyObjectB();
+		object.myProperty = Either3.forSecond(7);
+		assertSerialize("{\"myProperty\":7}", object);
+	}
+
+	@Test
+	public void testParseEither3() {
+		MyObjectB object = new MyObjectB();
+		object.myProperty = Either3.forSecond(7);
+		assertParse(object, "{\"myProperty\":7}");
+	}
+
+	protected static class MyObjectB {
+		public Either3<String, Integer, Boolean> myProperty;
+
+		@Override
+		public boolean equals(Object obj) {
+			if (obj instanceof MyObjectB) {
+				MyObjectB other = (MyObjectB) obj;
+				return this.myProperty == null && other.myProperty == null
+						|| this.myProperty != null && this.myProperty.equals(other.myProperty);
+			}
+			return false;
+		}
+
+		@Override
+		public int hashCode() {
+			if (myProperty != null)
+				return myProperty.hashCode();
+			return 0;
+		}
+	}
+
+	@Test
+	public void testSerializeJsonObject() {
+		MyObjectC object = new MyObjectC();
+		JsonObject jsonObject = new JsonObject();
+		jsonObject.addProperty("foo", "bar");
+		object.myProperty = Either.forRight(jsonObject);
+		assertSerialize("{\"myProperty\":{\"foo\":\"bar\"}}", object);
+	}
+
+	@Test
+	public void testParseJsonObject() {
+		MyObjectC object = new MyObjectC();
+		JsonObject jsonObject = new JsonObject();
+		jsonObject.addProperty("foo", "bar");
+		object.myProperty = Either.forRight(jsonObject);
+		assertParse(object, "{\"myProperty\":{\"foo\":\"bar\"}}");
+	}
+
+	protected static class MyObjectC {
+		public Either<String, Object> myProperty;
+
+		@Override
+		public boolean equals(Object obj) {
+			if (obj instanceof MyObjectC) {
+				MyObjectC other = (MyObjectC) obj;
+				return Objects.equals(this.myProperty, other.myProperty);
+			}
+			return false;
+		}
+
+		@Override
+		public int hashCode() {
+			return Objects.hashCode(this.myProperty);
+		}
+	}
+
+	@Test
+	public void testSerializeJsonObjectEither3() {
+		MyObjectD object = new MyObjectD();
+		JsonObject jsonObject = new JsonObject();
+		jsonObject.addProperty("foo", "bar");
+		object.myProperty = Either3.forThird(jsonObject);
+		assertSerialize("{\"myProperty\":{\"foo\":\"bar\"}}", object);
+	}
+
+	@Test
+	public void testParseJsonObjectEither3() {
+		MyObjectD object = new MyObjectD();
+		JsonObject jsonObject = new JsonObject();
+		jsonObject.addProperty("foo", "bar");
+		object.myProperty = Either3.forThird(jsonObject);
+		assertParse(object, "{\"myProperty\":{\"foo\":\"bar\"}}");
+	}
+
+	protected static class MyObjectD {
+		public Either3<String, Integer, Object> myProperty;
+
+		@Override
+		public boolean equals(Object obj) {
+			if (obj instanceof MyObjectD) {
+				MyObjectD other = (MyObjectD) obj;
+				return Objects.equals(this.myProperty, other.myProperty);
+			}
+			return false;
+		}
+
+		@Override
+		public int hashCode() {
+			return Objects.hashCode(this.myProperty);
+		}
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/test/json/MessageJsonHandlerTest.java b/javatests/org/eclipse/lsp4j/jsonrpc/test/json/MessageJsonHandlerTest.java
new file mode 100644
index 0000000..5d648b1
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/test/json/MessageJsonHandlerTest.java
@@ -0,0 +1,783 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.test.json;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Consumer;
+
+import org.eclipse.lsp4j.jsonrpc.json.JsonRpcMethod;
+import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.messages.Message;
+import org.eclipse.lsp4j.jsonrpc.messages.NotificationMessage;
+import org.eclipse.lsp4j.jsonrpc.messages.RequestMessage;
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseError;
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.google.gson.reflect.TypeToken;
+
+public class MessageJsonHandlerTest {
+
+	public static class Entry {
+		public String name;
+		public int kind;
+		public Location location;
+	}
+
+	public static class Location {
+		public String uri;
+	}
+
+	@SuppressWarnings({ "unchecked" })
+	@Test
+	public void testParseList_01() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<List<? extends Entry>>() {}.getType(),
+				new TypeToken<List<? extends Entry>>() {}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id)->"foo");
+		Message message = handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n" 
+				+ " \"result\": [\n"
+				+ "  {\"name\":\"$schema\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":1,\"character\":3},\"end\":{\"line\":1,\"character\":55}}}},\n"
+				+ "  {\"name\":\"type\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":2,\"character\":3},\"end\":{\"line\":2,\"character\":19}}}},\n"
+				+ "  {\"name\":\"title\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":3,\"character\":3},\"end\":{\"line\":3,\"character\":50}}}},\n"
+				+ "  {\"name\":\"additionalProperties\",\"kind\":17,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":4,\"character\":4},\"end\":{\"line\":4,\"character\":32}}}},\n"
+				+ "  {\"name\":\"properties\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":5,\"character\":3},\"end\":{\"line\":5,\"character\":20}}}}\n"
+				+ "]}");
+		List<? extends Entry> result = (List<? extends Entry>) ((ResponseMessage) message).getResult();
+		Assert.assertEquals(5, result.size());
+		for (Entry e : result) {
+			Assert.assertTrue(e.location.uri, e.location.uri.startsWith("file:/home/mistria"));
+		}
+	}
+	
+	@SuppressWarnings({ "unchecked" })
+	@Test
+	public void testParseList_02() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Set<Entry>>() {}.getType(),
+				new TypeToken<Set<Entry>>() {}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id)->"foo");
+		Message message = handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n" 
+				+ " \"result\": [\n"
+				+ "  {\"name\":\"$schema\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":1,\"character\":3},\"end\":{\"line\":1,\"character\":55}}}},\n"
+				+ "  {\"name\":\"type\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":2,\"character\":3},\"end\":{\"line\":2,\"character\":19}}}},\n"
+				+ "  {\"name\":\"title\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":3,\"character\":3},\"end\":{\"line\":3,\"character\":50}}}},\n"
+				+ "  {\"name\":\"additionalProperties\",\"kind\":17,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":4,\"character\":4},\"end\":{\"line\":4,\"character\":32}}}},\n"
+				+ "  {\"name\":\"properties\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":5,\"character\":3},\"end\":{\"line\":5,\"character\":20}}}}\n"
+				+ "]}");
+		Set<Entry> result = (Set<Entry>) ((ResponseMessage)message).getResult();
+		Assert.assertEquals(5, result.size());
+		for (Entry e : result) {
+			Assert.assertTrue(e.location.uri, e.location.uri.startsWith("file:/home/mistria"));
+		}
+	}
+
+	@Test
+	public void testParseNullList() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<List<? extends Entry>>() {}.getType(),
+				new TypeToken<List<? extends Entry>>() {}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id)->"foo");
+		Message message = handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ " \"result\": null}");
+		Assert.assertNull(((ResponseMessage)message).getResult());
+	}
+
+	@SuppressWarnings({ "unchecked" })
+	@Test
+	public void testParseEmptyList() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<List<? extends Entry>>() {}.getType(),
+				new TypeToken<List<? extends Entry>>() {}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id)->"foo");
+		Message message = handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ " \"result\": []}");
+		List<Entry> result = (List<Entry>) ((ResponseMessage)message).getResult();
+		Assert.assertEquals(0, result.size());
+	}
+
+	@Test
+	public void testSerializeEmptyList() {
+		MessageJsonHandler handler = new MessageJsonHandler(Collections.emptyMap());
+		NotificationMessage message = new NotificationMessage();
+		message.setMethod("foo");
+		message.setParams(Collections.EMPTY_LIST);
+		String json = handler.serialize(message);
+		Assert.assertEquals("{\"jsonrpc\":\"2.0\",\"method\":\"foo\",\"params\":[]}", json);
+	}
+	
+	@Test
+	public void testSerializeImmutableList() {
+		MessageJsonHandler handler = new MessageJsonHandler(Collections.emptyMap());
+		NotificationMessage message = new NotificationMessage();
+		message.setMethod("foo");
+		List<Object> list = new ArrayList<>();
+		list.add("a");
+		list.add("b");
+		message.setParams(Collections.unmodifiableList(list));
+		String json = handler.serialize(message);
+		Assert.assertEquals("{\"jsonrpc\":\"2.0\",\"method\":\"foo\",\"params\":[\"a\",\"b\"]}", json);
+	}
+	
+	@SuppressWarnings({ "unchecked" })
+	@Test
+	public void testEither_01() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Either<String, List<Map<String,String>>>>() {}.getType(),
+				new TypeToken<Either<String, Integer>>() {}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		Message message = handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ " \"result\": [\n"
+				+ "  {\"name\":\"foo\"},\n"
+				+ "  {\"name\":\"bar\"}\n"
+				+ "]}");
+		Either<String, List<Map<String, String>>> result = (Either<String, List<Map<String,String>>>) ((ResponseMessage)message).getResult();
+		Assert.assertTrue(result.isRight());
+		for (Map<String, String> e : result.getRight()) {
+			Assert.assertNotNull(e.get("name"));
+		}
+		message = handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n" 
+				+ "\"result\": \"name\"\n"
+				+ "}");
+		result = (Either<String, List<Map<String,String>>>) ((ResponseMessage)message).getResult();
+		Assert.assertFalse(result.isRight());
+		Assert.assertEquals("name", result.getLeft());
+	}
+	
+	@SuppressWarnings({ "unchecked" })
+	@Test
+	public void testEither_02() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Either<MyEnum, Map<String,String>>>() {}.getType(),
+				new TypeToken<Object>() {}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		Message message = handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ "\"result\": 2\n"
+				+ "}");
+		Either<MyEnum, List<Map<String, String>>> result = (Either<MyEnum, List<Map<String,String>>>) ((ResponseMessage)message).getResult();
+		Assert.assertTrue(result.isLeft());
+		Assert.assertEquals(MyEnum.B, result.getLeft());
+	}
+	
+	@SuppressWarnings({ "unchecked" })
+	@Test
+	public void testEither_03() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Either<Either<MyEnum, Map<String,String>>, List<Either<MyEnum, Map<String,String>>>>>() {}.getType(),
+				new TypeToken<Object>() {}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+
+		Message message = handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ "\"result\": 2\n"
+				+ "}");
+		Either<Either<MyEnum, Map<String,String>>, List<Either<MyEnum, Map<String,String>>>> result = (Either<Either<MyEnum, Map<String, String>>, List<Either<MyEnum, Map<String, String>>>>) ((ResponseMessage)message).getResult();
+		Assert.assertTrue(result.isLeft());
+		Assert.assertTrue(result.getLeft().isLeft());
+		Assert.assertEquals(MyEnum.B, result.getLeft().getLeft());
+
+		message = handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ " \"result\": {\n"
+				+ "  \"foo\":\"1\",\n"
+				+ "  \"bar\":\"2\"\n"
+				+ "}}");
+		result = (Either<Either<MyEnum, Map<String, String>>, List<Either<MyEnum, Map<String, String>>>>) ((ResponseMessage)message).getResult();
+		Assert.assertTrue(result.isLeft());
+		Assert.assertTrue(result.getLeft().isRight());
+		Assert.assertEquals("1", result.getLeft().getRight().get("foo"));
+		Assert.assertEquals("2", result.getLeft().getRight().get("bar"));
+
+		message = handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ " \"result\": [{\n"
+				+ "  \"foo\":\"1\",\n"
+				+ "  \"bar\":\"2\"\n"
+				+ "}]}");
+		result = (Either<Either<MyEnum, Map<String, String>>, List<Either<MyEnum, Map<String, String>>>>) ((ResponseMessage)message).getResult();
+		Assert.assertTrue(result.isRight());
+		Assert.assertTrue(result.getRight().get(0).isRight());
+		Assert.assertEquals("1", result.getRight().get(0).getRight().get("foo"));
+		Assert.assertEquals("2", result.getRight().get(0).getRight().get("bar"));
+		
+		message = handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ " \"result\": [\n"
+				+ "  2\n"
+				+ "]}");
+		result = (Either<Either<MyEnum, Map<String, String>>, List<Either<MyEnum, Map<String, String>>>>) ((ResponseMessage)message).getResult();
+		Assert.assertTrue(result.isRight());
+		Assert.assertTrue(result.getRight().get(0).isLeft());
+		Assert.assertEquals(MyEnum.B, result.getRight().get(0).getLeft());
+	}
+	
+	@SuppressWarnings({ "unchecked" })
+	@Test
+	public void testEither_04() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Either<MyClass, List<? extends MyClass>>>() {}.getType(),
+				new TypeToken<Object>() {}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+
+		Message message = handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ "\"result\": {\n"
+				+ "  value:\"foo\"\n"
+				+ "}}");
+		Either<MyClass, List<? extends MyClass>> result = (Either<MyClass, List<? extends MyClass>>) ((ResponseMessage)message).getResult();
+		Assert.assertTrue(result.isLeft());
+		Assert.assertEquals("foo", result.getLeft().getValue());
+		
+		message = handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ "\"result\": [{\n"
+				+ "  value:\"bar\"\n"
+				+ "}]}");
+		result = (Either<MyClass, List<? extends MyClass>>) ((ResponseMessage)message).getResult();
+		Assert.assertTrue(result.isRight());
+		Assert.assertEquals("bar", result.getRight().get(0).getValue());
+	}
+	
+	@SuppressWarnings({ "unchecked" })
+	@Test
+	public void testEither_05() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Either<List<MyClass>, MyClassList>>() {}.getType(),
+				new TypeToken<Object>() {}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+
+		Message message = handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ "\"result\": [{\n"
+				+ "  value:\"foo\"\n"
+				+ "}]}");
+		Either<List<MyClass>, MyClassList> result = (Either<List<MyClass>, MyClassList>) ((ResponseMessage)message).getResult();
+		Assert.assertTrue(result.isLeft());
+		Assert.assertEquals("foo", result.getLeft().get(0).getValue());
+		
+		message = handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ "\"result\": {\n"
+				+ "  items: [{\n"
+				+ "    value:\"bar\"\n"
+				+ "}]}}");
+		result = (Either<List<MyClass>, MyClassList>) ((ResponseMessage)message).getResult();
+		Assert.assertTrue(result.isRight());
+		Assert.assertEquals("bar", result.getRight().getItems().get(0).getValue());
+	}
+	
+	@Test
+	public void testParamsParsing_01() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<Location>() {}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		
+		RequestMessage message = (RequestMessage) handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ "\"params\": {\"uri\": \"dummy://mymodel.mydsl\"},\n"
+				+ "\"method\":\"foo\"\n"
+				+ "}");
+		Assert.assertEquals(Location.class, message.getParams().getClass());
+	}
+	
+	@Test
+	public void testParamsParsing_02() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<Location>() {}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		
+		RequestMessage message = (RequestMessage) handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ "\"method\":\"foo\",\n"
+				+ "\"params\": {\"uri\": \"dummy://mymodel.mydsl\"}\n"
+				+ "}");
+		Assert.assertEquals(Location.class, message.getParams().getClass());
+	}
+	
+	@Test
+	public void testParamsParsing_03() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<Location>() {}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		
+		RequestMessage message = (RequestMessage) handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ "\"method\":\"bar\",\n"
+				+ "\"params\": {\"uri\": \"dummy://mymodel.mydsl\"}\n"
+				+ "}");
+		Assert.assertEquals(JsonObject.class, message.getParams().getClass());
+	}
+	
+	@Test
+	public void testParamsParsing_04() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<Location>() {}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		
+		RequestMessage message = (RequestMessage) handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ "\"method\":\"bar\",\n"
+				+ "\"params\": null\n"
+				+ "}");
+		Assert.assertEquals(null, message.getParams());
+	}
+	
+	@Test
+	public void testRawMultiParamsParsing_01() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<String>() {}.getType(),
+				new TypeToken<Integer>() {}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		
+		RequestMessage message = (RequestMessage) handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ "\"method\":\"foo\",\n"
+				+ "\"params\": [\"foo\", 2]\n"
+				+ "}");
+		Assert.assertTrue("" + message.getParams().getClass(), message.getParams() instanceof List);
+
+		List<?> parameters = (List<?>) message.getParams();
+		Assert.assertEquals(2, parameters.size());
+		Assert.assertEquals("foo", parameters.get(0));
+		Assert.assertEquals(2, parameters.get(1));
+	}
+	
+	@Test
+	public void testRawMultiParamsParsing_02() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<String>() {}.getType(),
+				new TypeToken<Integer>() {}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		
+		RequestMessage message = (RequestMessage) handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ "\"method\":\"bar\",\n"
+				+ "\"params\": [\"foo\", 2]\n"
+				+ "}");
+		Assert.assertTrue("" + message.getParams().getClass(), message.getParams() instanceof JsonArray);
+	}
+
+	@Test
+	public void testRawMultiParamsParsing_03() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<List<String>>() {}.getType(),
+				new TypeToken<List<Integer>>() {}.getType(),
+				new TypeToken<Location>() {}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		
+		RequestMessage message = (RequestMessage) handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ "\"method\":\"foo\",\n"
+				+ "\"params\": [[\"foo\", \"bar\"], [1, 2], {\"uri\": \"dummy://mymodel.mydsl\"}]\n"
+				+ "}");
+		Assert.assertTrue("" + message.getParams().getClass(), message.getParams() instanceof List);
+
+		List<?> parameters = (List<?>) message.getParams();
+		Assert.assertEquals(3, parameters.size());
+		Assert.assertEquals("[foo, bar]", parameters.get(0).toString());
+		Assert.assertEquals("[1, 2]", parameters.get(1).toString());
+		Assert.assertTrue("" + parameters.get(2).getClass(), parameters.get(2) instanceof Location);
+	}
+
+	@Test
+	public void testRawMultiParamsParsing_04() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<List<String>>() {}.getType(),
+				new TypeToken<List<Integer>>() {}.getType(),
+				new TypeToken<Location>() {}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		
+		RequestMessage message = (RequestMessage) handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ "\"method\":\"foo\",\n"
+				+ "\"params\": [[\"foo\", \"bar\"], [1, 2]]\n"
+				+ "}");
+		Assert.assertTrue("" + message.getParams().getClass(), message.getParams() instanceof List);
+
+		List<?> parameters = (List<?>) message.getParams();
+		Assert.assertEquals(3, parameters.size());
+		Assert.assertEquals("[foo, bar]", parameters.get(0).toString());
+		Assert.assertEquals("[1, 2]", parameters.get(1).toString());
+		Assert.assertNull(parameters.get(2));
+	}
+	
+	@Test
+	public void testMultiParamsParsing_01() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<String>() {}.getType(),
+				new TypeToken<Integer>() {}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		
+		RequestMessage message = (RequestMessage) handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ "\"params\": [\"foo\", 2],\n"
+				+ "\"method\":\"foo\"\n"
+				+ "}");
+		Assert.assertTrue("" + message.getParams().getClass(), message.getParams() instanceof List);
+
+		List<?> parameters = (List<?>) message.getParams();
+		Assert.assertEquals(2, parameters.size());
+		Assert.assertEquals("foo", parameters.get(0));
+		Assert.assertEquals(2, parameters.get(1));
+	}
+	
+	@Test
+	public void testMultiParamsParsing_02() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<String>() {}.getType(),
+				new TypeToken<Integer>() {}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		
+		RequestMessage message = (RequestMessage) handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ "\"params\": [\"foo\", 2],\n"
+				+ "\"method\":\"bar\"\n"
+				+ "}");
+		Assert.assertTrue("" + message.getParams().getClass(), message.getParams() instanceof JsonArray);
+	}
+	
+	@Test
+	public void testMultiParamsParsing_03() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<List<String>>() {}.getType(),
+				new TypeToken<List<Integer>>() {}.getType(),
+				new TypeToken<Location>() {}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		
+		RequestMessage message = (RequestMessage) handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ "\"params\": [[\"foo\", \"bar\"], [1, 2], {\"uri\": \"dummy://mymodel.mydsl\"}],\n"
+				+ "\"method\":\"foo\"\n"
+				+ "}");
+		Assert.assertTrue("" + message.getParams().getClass(), message.getParams() instanceof List);
+
+		List<?> parameters = (List<?>) message.getParams();
+		Assert.assertEquals(3, parameters.size());
+		Assert.assertEquals("[foo, bar]", parameters.get(0).toString());
+		Assert.assertEquals("[1, 2]", parameters.get(1).toString());
+		Assert.assertTrue("" + parameters.get(2).getClass(), parameters.get(2) instanceof Location);
+	}
+	
+	@Test
+	public void testMultiParamsParsing_04() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<List<String>>() {}.getType(),
+				new TypeToken<List<Integer>>() {}.getType(),
+				new TypeToken<Location>() {}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		
+		RequestMessage message = (RequestMessage) handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ "\"params\": [[\"foo\", \"bar\"], [1, 2]],\n"
+				+ "\"method\":\"foo\"\n"
+				+ "}");
+		Assert.assertTrue("" + message.getParams().getClass(), message.getParams() instanceof List);
+
+		List<?> parameters = (List<?>) message.getParams();
+		Assert.assertEquals(3, parameters.size());
+		Assert.assertEquals("[foo, bar]", parameters.get(0).toString());
+		Assert.assertEquals("[1, 2]", parameters.get(1).toString());
+		Assert.assertNull(parameters.get(2));
+	}
+
+	@Test
+	public void testEnumParam() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<List<MyEnum>>() {}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		RequestMessage message = (RequestMessage) handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ "\"params\": [1, 2, 3],\n"
+				+ "\"method\":\"foo\"\n"
+				+ "}");
+		Assert.assertTrue("" + message.getParams().getClass(), message.getParams() instanceof List);
+
+		List<?> parameters = (List<?>) message.getParams();
+		Assert.assertEquals(Arrays.asList(MyEnum.A, MyEnum.B, MyEnum.C),
+				parameters);
+	}
+
+	@Test
+	public void testEnumParamNull() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<List<MyEnum>>() {}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		RequestMessage message = (RequestMessage) handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ "\"params\": [1, 2, null],\n"
+				+ "\"method\":\"foo\"\n"
+				+ "}");
+		Assert.assertTrue("" + message.getParams().getClass(), message.getParams() instanceof List);
+
+		List<?> parameters = (List<?>) message.getParams();
+		Assert.assertEquals(Arrays.asList(MyEnum.A, MyEnum.B, null),
+				parameters);
+	}
+
+	@Test
+	public void testResponseErrorData() {
+		MessageJsonHandler handler = new MessageJsonHandler(Collections.emptyMap());
+		ResponseMessage message = (ResponseMessage) handler.parseMessage("{\"jsonrpc\":\"2.0\","
+				+ "\"id\":\"2\",\n"
+				+ "\"error\": { \"code\": -32001, \"message\": \"foo\",\n"
+				+ "    \"data\": { \"uri\": \"file:/foo\", \"version\": 5, \"list\": [\"a\", \"b\", \"c\"] }\n"
+				+ "  }\n"
+				+ "}");
+		ResponseError error = message.getError();
+		Assert.assertTrue("Expected a JsonObject in error.data", error.getData() instanceof JsonObject);
+		JsonObject data = (JsonObject) error.getData();
+		Assert.assertEquals("file:/foo", data.get("uri").getAsString());
+		Assert.assertEquals(5, data.get("version").getAsInt());
+		JsonArray list = data.get("list").getAsJsonArray();
+		Assert.assertEquals("a", list.get(0).getAsString());
+		Assert.assertEquals("b", list.get(1).getAsString());
+		Assert.assertEquals("c", list.get(2).getAsString());
+	}
+
+	public static final <T> void swap(T[] a, int i, int j) {
+		T t = a[i];
+		a[i] = a[j];
+		a[j] = t;
+	}
+
+	public <T> void testAllPermutationsInner(T[] array, int i, int n, Consumer<T[]> test) {
+		int j;
+		if (i == n) {
+			test.accept(array);
+		} else {
+			for (j = i; j <= n; j++) {
+				swap(array, i, j);
+				testAllPermutationsInner(array, i + 1, n, test);
+				swap(array, i, j);
+			}
+		}
+	}
+
+	public <T> void testAllPermutationsStart(T[] array, Consumer<T[]> test) {
+		testAllPermutationsInner(array, 0, array.length - 1, test);
+	}
+
+	public void testAllPermutations(String[] properties, Consumer<String> test) {
+		testAllPermutationsStart(properties, mutatedProperties -> {
+			StringBuilder json = new StringBuilder();
+			json.append("{");
+			for (int k = 0; k < mutatedProperties.length; k++) {
+				json.append(mutatedProperties[k]);
+				if (k != mutatedProperties.length - 1) {
+					json.append(",");
+				}
+
+			}
+			json.append("}");
+			String jsonString = json.toString();
+			try {
+				test.accept(jsonString);
+			} catch (Exception | AssertionError e) {
+				// To make it easier to debug a failing test, add another exception
+				// layer that shows the version of the json used -- you may
+				// need to turn off "Filter Stack Trace" in JUnit view in Eclipse
+				// to see the underlying error.
+				throw new AssertionError("Failed with this input json: " + jsonString, e);
+			}
+		});
+	}
+
+	@Test
+	public void testThePermutationsTest() {
+		// make sure that the testAllPermutations works as expected
+		Set<String> collectedPermutations = new HashSet<>();
+		Set<String> expectedPermutations = new HashSet<>();
+		expectedPermutations.add("{a,b,c}");
+		expectedPermutations.add("{a,c,b}");
+		expectedPermutations.add("{b,a,c}");
+		expectedPermutations.add("{b,c,a}");
+		expectedPermutations.add("{c,a,b}");
+		expectedPermutations.add("{c,b,a}");
+		testAllPermutations(new String[] {"a", "b", "c"}, perm -> collectedPermutations.add(perm));
+		Assert.assertEquals(expectedPermutations, collectedPermutations);
+	}
+
+	@Test
+	public void testRequest_AllOrders() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<Location>() {
+				}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		String[] properties = new String[] {
+				"\"jsonrpc\":\"2.0\"",
+				"\"id\":2",
+				"\"method\":\"foo\"",
+				"\"params\": {\"uri\": \"dummy://mymodel.mydsl\"}"
+				};
+		testAllPermutations(properties, json -> {
+			RequestMessage message = (RequestMessage) handler.parseMessage(json);
+			Object params = message.getParams();
+			Class<? extends Object> class1 = params.getClass();
+			Assert.assertEquals(Location.class, class1);
+			Assert.assertEquals("dummy://mymodel.mydsl", ((Location)params).uri);
+		});
+	}
+
+	@Test
+	public void testNormalResponse_AllOrders() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Location>() {}.getType(),
+				new TypeToken<Void>() {
+				}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		String[] properties = new String[] {
+				"\"jsonrpc\":\"2.0\"",
+				"\"id\":2",
+				"\"result\": {\"uri\": \"dummy://mymodel.mydsl\"}"
+				};
+		testAllPermutations(properties, json -> {
+			ResponseMessage message = (ResponseMessage) handler.parseMessage(json);
+			Object result = message.getResult();
+			Class<? extends Object> class1 = result.getClass();
+			Assert.assertEquals(Location.class, class1);
+			Assert.assertEquals("dummy://mymodel.mydsl", ((Location)result).uri);
+			Assert.assertNull(message.getError());
+		});
+	}
+
+	@Test
+	public void testErrorResponse_AllOrders() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Location>() {}.getType(),
+				new TypeToken<Void>() {
+				}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		String[] properties = new String[] {
+				"\"jsonrpc\":\"2.0\"",
+				"\"id\":2",
+				"\"message\": \"failed\"",
+				"\"error\": {\"code\": 123456, \"message\": \"failed\", \"data\": {\"uri\": \"failed\"}}"
+				};
+		testAllPermutations(properties, json -> {
+			ResponseMessage message = (ResponseMessage) handler.parseMessage(json);
+			Assert.assertEquals("failed", message.getError().getMessage());
+			Object data = message.getError().getData();
+			JsonObject expected = new JsonObject();
+			expected.addProperty("uri", "failed");
+			Assert.assertEquals(expected, data);
+			Assert.assertNull(message.getResult());
+		});
+	}
+
+	@Test
+	public void testNotification_AllOrders() {
+		Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>();
+		supportedMethods.put("foo", JsonRpcMethod.request("foo",
+				new TypeToken<Void>() {}.getType(),
+				new TypeToken<Location>() {
+				}.getType()));
+		MessageJsonHandler handler = new MessageJsonHandler(supportedMethods);
+		handler.setMethodProvider((id) -> "foo");
+		String[] properties = new String[] {
+				"\"jsonrpc\":\"2.0\"",
+				"\"method\":\"foo\"",
+				"\"params\": {\"uri\": \"dummy://mymodel.mydsl\"}"
+				};
+		testAllPermutations(properties, json -> {
+			NotificationMessage message = (NotificationMessage) handler.parseMessage(json);
+			Object params = message.getParams();
+			Class<? extends Object> class1 = params.getClass();
+			Assert.assertEquals(Location.class, class1);
+			Assert.assertEquals("dummy://mymodel.mydsl", ((Location)params).uri);
+		});
+	}
+}
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/test/json/MessageProducerTest.java b/javatests/org/eclipse/lsp4j/jsonrpc/test/json/MessageProducerTest.java
new file mode 100644
index 0000000..7d7b4f3
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/test/json/MessageProducerTest.java
@@ -0,0 +1,124 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.test.json;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InterruptedIOException;
+import java.net.SocketException;
+import java.nio.channels.ClosedChannelException;
+import java.util.Collections;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.eclipse.lsp4j.jsonrpc.JsonRpcException;
+import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
+import org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class MessageProducerTest {
+	
+	private static final long TIMEOUT = 2000;
+	
+	private ExecutorService executorService;
+	private Level logLevel;
+	
+	@Before
+	public void setup() {
+		executorService = Executors.newCachedThreadPool();
+		Logger logger = Logger.getLogger(StreamMessageProducer.class.getName());
+		logLevel = logger.getLevel();
+		logger.setLevel(Level.SEVERE);
+	}
+	
+	@After
+	public void teardown() {
+		executorService.shutdown();
+		Logger logger = Logger.getLogger(StreamMessageProducer.class.getName());
+		logger.setLevel(logLevel);
+	}
+	
+	@Test
+	public void testStopOnInterrrupt() throws Exception {
+		executorService.submit(() -> {
+			InputStream input = new InputStream() {
+				@Override
+				public int read() throws IOException {
+					throw new InterruptedIOException();
+				}
+			};
+			MessageJsonHandler jsonHandler = new MessageJsonHandler(Collections.emptyMap());
+			StreamMessageProducer messageProducer = new StreamMessageProducer(input, jsonHandler);
+			messageProducer.listen(message -> {});
+			messageProducer.close();
+		}).get(TIMEOUT, TimeUnit.MILLISECONDS);
+	}
+	
+	@Test
+	public void testStopOnChannelClosed() throws Exception {
+		executorService.submit(() -> {
+			InputStream input = new InputStream() {
+				@Override
+				public int read() throws IOException {
+					throw new ClosedChannelException();
+				}
+			};
+			MessageJsonHandler jsonHandler = new MessageJsonHandler(Collections.emptyMap());
+			StreamMessageProducer messageProducer = new StreamMessageProducer(input, jsonHandler);
+			messageProducer.listen(message -> {});
+			messageProducer.close();
+		}).get(TIMEOUT, TimeUnit.MILLISECONDS);
+	}
+	
+	@Test
+	public void testStopOnSocketClosed() throws Throwable {
+		executorService.submit(() -> {
+			InputStream input = new InputStream() {
+				@Override
+				public int read() throws IOException {
+					throw new SocketException("Socket closed");
+				}
+			};
+			MessageJsonHandler jsonHandler = new MessageJsonHandler(Collections.emptyMap());
+			StreamMessageProducer messageProducer = new StreamMessageProducer(input, jsonHandler);
+			messageProducer.listen(message -> {});
+			messageProducer.close();
+		}).get(TIMEOUT, TimeUnit.MILLISECONDS);
+	}
+	
+	@Test(expected=JsonRpcException.class)
+	public void testIOException() throws Throwable {
+		try {
+			executorService.submit(() -> {
+				InputStream input = new InputStream() {
+					@Override
+					public int read() throws IOException {
+						throw new SocketException("Permission denied: connect");
+					}
+				};
+				MessageJsonHandler jsonHandler = new MessageJsonHandler(Collections.emptyMap());
+				StreamMessageProducer messageProducer = new StreamMessageProducer(input, jsonHandler);
+				messageProducer.listen(message -> {});
+				messageProducer.close();
+			}).get(TIMEOUT, TimeUnit.MILLISECONDS);
+		} catch (ExecutionException e) {
+			throw e.getCause();
+		}
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/test/json/MyClass.java b/javatests/org/eclipse/lsp4j/jsonrpc/test/json/MyClass.java
new file mode 100644
index 0000000..fa0a6cd
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/test/json/MyClass.java
@@ -0,0 +1,53 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.test.json;
+
+public class MyClass {
+
+	private String value;
+
+	public String getValue() {
+		return value;
+	}
+
+	public void setValue(String value) {
+		this.value = value;
+	}
+
+	public String toString() {
+		return "MyClass [value=" + value + "]";
+	}
+
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((value == null) ? 0 : value.hashCode());
+		return result;
+	}
+
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MyClass other = (MyClass) obj;
+		if (value == null) {
+			if (other.value != null)
+				return false;
+		} else if (!value.equals(other.value))
+			return false;
+		return true;
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/test/json/MyClassList.java b/javatests/org/eclipse/lsp4j/jsonrpc/test/json/MyClassList.java
new file mode 100644
index 0000000..718856d
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/test/json/MyClassList.java
@@ -0,0 +1,56 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.test.json;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MyClassList {
+
+	private List<MyClass> items = new ArrayList<>();
+
+	public List<MyClass> getItems() {
+		return items;
+	}
+
+	public void setItems(List<MyClass> items) {
+		this.items = items;
+	}
+
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((items == null) ? 0 : items.hashCode());
+		return result;
+	}
+
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MyClassList other = (MyClassList) obj;
+		if (items == null) {
+			if (other.items != null)
+				return false;
+		} else if (!items.equals(other.items))
+			return false;
+		return true;
+	}
+
+	public String toString() {
+		return "MyClassList [items=" + items + "]";
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/test/json/MyEnum.java b/javatests/org/eclipse/lsp4j/jsonrpc/test/json/MyEnum.java
new file mode 100644
index 0000000..56ef630
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/test/json/MyEnum.java
@@ -0,0 +1,37 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.test.json;
+
+public enum MyEnum {
+	
+	A(1),
+	B(2),
+	C(3);
+	
+	private final int value;
+	
+	MyEnum(int value) {
+		this.value = value;
+	}
+	
+	public int getValue() {
+		return value;
+	}
+	
+	public static MyEnum forValue(int value) {
+		MyEnum[] allValues = MyEnum.values();
+		if (value < 1 || value > allValues.length)
+			throw new IllegalArgumentException("Illegal enum value: " + value);
+		return allValues[value - 1];
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/test/json/ThrowableTest.java b/javatests/org/eclipse/lsp4j/jsonrpc/test/json/ThrowableTest.java
new file mode 100644
index 0000000..445cf16
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/test/json/ThrowableTest.java
@@ -0,0 +1,108 @@
+/******************************************************************************
+ * Copyright (c) 2017-2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.test.json;
+
+import java.util.Objects;
+
+import org.eclipse.lsp4j.jsonrpc.json.adapters.ThrowableTypeAdapter;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+
+public class ThrowableTest {
+
+	protected Gson createGson() {
+		return new GsonBuilder().registerTypeAdapterFactory(new ThrowableTypeAdapter.Factory()).create();
+	}
+
+	protected void assertSerialize(Object object, String expected) {
+		Gson gson = createGson();
+		String actual = gson.toJson(object);
+		Assert.assertEquals(expected, actual);
+	}
+
+	protected void assertParse(MyObjectA expected, String string) {
+		Gson gson = createGson();
+		MyObjectA actual = (MyObjectA)gson.fromJson(string, expected.getClass());
+		Assert.assertEquals(expected.otherProperty, actual.otherProperty);
+		assertEquals(expected.myThrowable, actual.myThrowable);
+	}
+
+	protected void assertEquals(Throwable expected, Throwable actual) {
+		if (Objects.equals(expected, actual))
+			return;
+		Assert.assertEquals(expected.getMessage(), actual.getMessage());
+		assertEquals(expected.getCause(), actual.getCause());
+	}
+
+	@Test
+	public void testSerializeThrowable() {
+		MyObjectA object = new MyObjectA();
+		object.myThrowable = new Throwable("message");
+		assertSerialize(object, "{\"myThrowable\":{\"message\":\"message\"}}");
+	}
+
+	@Test
+	public void testSerializeThrowableWithCause() {
+		MyObjectA object = new MyObjectA();
+		object.myThrowable = new Throwable("message", new Throwable("cause"));
+		assertSerialize(object, "{\"myThrowable\":{\"message\":\"message\",\"cause\":{\"message\":\"cause\"}}}");
+	}
+
+	@Test
+	public void testSerializeThrowableWithRecursiveCause() {
+		MyObjectA object = new MyObjectA();
+		object.myThrowable = new Throwable("message");
+		object.myThrowable = new Throwable(object.myThrowable.getMessage(), object.myThrowable);
+		assertSerialize(object, "{\"myThrowable\":{\"message\":\"message\"}}");
+	}
+
+	@Test
+	public void testSerializeNull() {
+		MyObjectA object = new MyObjectA();
+		object.myThrowable = null;
+		object.otherProperty = "ok";
+		assertSerialize(object, "{\"otherProperty\":\"ok\"}");
+		object.toString();
+	}
+
+	@Test
+	public void testParseThrowable() {
+		MyObjectA object = new MyObjectA();
+		object.myThrowable = new Throwable("message");
+		assertParse(object, "{\"myThrowable\":{\"message\":\"message\"}}");
+	}
+
+	@Test
+	public void testParseThrowableWithCause() {
+		MyObjectA object = new MyObjectA();
+		object.myThrowable = new Throwable("message", new Throwable("cause"));
+		assertParse(object, "{\"myThrowable\":{\"message\":\"message\",\"cause\":{\"message\":\"cause\"}}}");
+	}
+
+	@Test
+	public void testParseNull() {
+		MyObjectA object = new MyObjectA();
+		object.myThrowable = null;
+		object.otherProperty = "ok";
+		assertParse(object, "{\"myThrowable\":null, \"otherProperty\": \"ok\"}");
+		object.toString();
+	}
+
+	protected static class MyObjectA {
+		public Throwable myThrowable;
+		public String otherProperty;
+	}
+}
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/test/json/TuplesTest.java b/javatests/org/eclipse/lsp4j/jsonrpc/test/json/TuplesTest.java
new file mode 100644
index 0000000..37f0cf6
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/test/json/TuplesTest.java
@@ -0,0 +1,80 @@
+package org.eclipse.lsp4j.jsonrpc.test.json;
+
+import java.util.Objects;
+
+import org.eclipse.lsp4j.jsonrpc.json.adapters.TupleTypeAdapters;
+import org.eclipse.lsp4j.jsonrpc.messages.Tuple;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+public class TuplesTest {
+
+	protected static class MyObjectA {
+		public Tuple.Two<String, Integer> myProperty;
+		public String otherProperty;
+
+		@Override
+		public boolean equals(Object obj) {
+			if (obj instanceof MyObjectA) {
+				MyObjectA other = (MyObjectA) obj;
+				return Objects.equals(this.myProperty, other.myProperty) && Objects.equals(this.otherProperty, otherProperty);
+			}
+			return false;
+		}
+
+		@Override
+		public int hashCode() {
+			return Objects.hash(this.myProperty, this.otherProperty);
+		}
+	}
+
+	protected Gson createGson() {
+		return new GsonBuilder().registerTypeAdapterFactory(new TupleTypeAdapters.TwoTypeAdapterFactory()).create();
+	}
+
+	protected void assertSerialize(String expected, Object object) {
+		Gson gson = createGson();
+		String actual = gson.toJson(object);
+		Assert.assertEquals(expected, actual);
+	}
+
+	protected void assertParse(Object expected, String string) {
+		Gson gson = createGson();
+		Object actual = gson.fromJson(string, expected.getClass());
+		Assert.assertEquals(expected, actual);
+	}
+
+	@Test
+	public void testSerializeTwo() {
+		MyObjectA object = new MyObjectA();
+		object.myProperty = Tuple.two("Foo", 7);
+		assertSerialize("{\"myProperty\":[\"Foo\",7]}", object);
+	}
+
+	@Test
+	public void testSerializeNull() {
+		MyObjectA object = new MyObjectA();
+		object.myProperty = null;
+		object.otherProperty = "ok";
+		assertSerialize("{\"otherProperty\":\"ok\"}", object);
+	}
+
+	@Test
+	public void testParseTwo() {
+		MyObjectA object = new MyObjectA();
+		object.myProperty = Tuple.two("Foo", 7);
+		assertParse(object, "{\"myProperty\":[\"Foo\",7]}");
+	}
+
+	@Test
+	public void testParseNull() {
+		MyObjectA object = new MyObjectA();
+		object.myProperty = null;
+		object.otherProperty = "ok";
+		assertParse(object, "{\"myProperty\":null, \"otherProperty\": \"ok\"}");
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/test/json/TypeUtilsTest.java b/javatests/org/eclipse/lsp4j/jsonrpc/test/json/TypeUtilsTest.java
new file mode 100644
index 0000000..b163f07
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/test/json/TypeUtilsTest.java
@@ -0,0 +1,131 @@
+/******************************************************************************
+ * Copyright (c) 2017 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.test.json;
+
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.lsp4j.jsonrpc.json.adapters.TypeUtils;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.messages.Either3;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.google.gson.reflect.TypeToken;
+
+public class TypeUtilsTest {
+	
+	protected void assertElementTypes(TypeToken<?> typeToken, Class<?> targetType, Type... expectedElementTypes) {
+		Type[] actualElementTypes = TypeUtils.getElementTypes(typeToken, targetType);
+		Assert.assertArrayEquals(expectedElementTypes, actualElementTypes);
+	}
+	
+	@Test
+	public void testCollectionElement1() {
+		TypeToken<?> token = new TypeToken<List<String>>() {};
+		assertElementTypes(token, Collection.class, String.class);
+	}
+	
+	@Test
+	public void testCollectionElement2() {
+		TypeToken<?> token = new TypeToken<List<? extends Number>>() {};
+		assertElementTypes(token, Collection.class, Number.class);
+	}
+	
+	private static interface MyCollection extends Collection<String> {
+	}
+	
+	@Test
+	public void testCollectionElement3() {
+		TypeToken<?> token = new TypeToken<MyCollection>() {};
+		assertElementTypes(token, Collection.class, String.class);
+	}
+	
+	private static class MyLinkedList extends LinkedList<String> {
+		private static final long serialVersionUID = 1L;
+	}
+	
+	@Test
+	public void testCollectionElement4() {
+		TypeToken<?> token = new TypeToken<MyLinkedList>() {};
+		assertElementTypes(token, Collection.class, String.class);
+	}
+	
+	@Test
+	public void testCollectionElement5() {
+		TypeToken<?> token = new TypeToken<List<Either<List<String>, String>>>() {};
+		assertElementTypes(token, Collection.class, new TypeToken<Either<List<String>, String>>() {}.getType());
+	}
+	
+	@Test
+	public void testEitherElements1() {
+		TypeToken<?> token = new TypeToken<Either<String, Number>>() {};
+		assertElementTypes(token, Either.class, String.class, Number.class);
+	}
+	
+	@Test
+	public void testEitherElements2() {
+		TypeToken<?> token = new TypeToken<Either<String, ? extends Number>>() {};
+		assertElementTypes(token, Either.class, String.class, Number.class);
+	}
+	
+	private static class MyEitherA extends Either<String, Number> {
+		protected MyEitherA(String left, Number right) {
+			super(left, right);
+		}
+	}
+	
+	@Test
+	public void testEitherElements3() {
+		TypeToken<?> token = new TypeToken<MyEitherA>() {};
+		assertElementTypes(token, Either.class, String.class, Number.class);
+	}
+	
+	private static class MyEitherB<T> extends Either<String, T> {
+		protected MyEitherB(String left, T right) {
+			super(left, right);
+		}
+	}
+	
+	@Test
+	public void testEitherElements4() {
+		TypeToken<?> token = new TypeToken<MyEitherB<Number>>() {};
+		assertElementTypes(token, Either.class, String.class, Number.class);
+	}
+	
+	@Test
+	public void testEitherElements5() {
+		TypeToken<?> token = new TypeToken<Either3<String, Number, Boolean>>() {};
+		assertElementTypes(token, Either.class, String.class, new TypeToken<Either<Number, Boolean>>() {}.getType());
+	}
+	
+	@Test
+	public void testEitherElements6() {
+		TypeToken<?> token = new TypeToken<Either3<String, Number, Boolean>>() {};
+		assertElementTypes(token, Either3.class, String.class, Number.class, Boolean.class);
+	}
+	
+	private static class MyEitherC extends Either3<String, Number, Boolean> {
+		protected MyEitherC(String left, Either<Number, Boolean> right) {
+			super(left, right);
+		}
+	}
+	
+	@Test
+	public void testEitherElements7() {
+		TypeToken<?> token = new TypeToken<MyEitherC>() {};
+		assertElementTypes(token, Either.class, String.class, new TypeToken<Either<Number, Boolean>>() {}.getType());
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/jsonrpc/test/validation/ReflectiveMessageValidatorTest.java b/javatests/org/eclipse/lsp4j/jsonrpc/test/validation/ReflectiveMessageValidatorTest.java
new file mode 100644
index 0000000..207cfe3
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/jsonrpc/test/validation/ReflectiveMessageValidatorTest.java
@@ -0,0 +1,165 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.jsonrpc.test.validation;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.eclipse.lsp4j.jsonrpc.MessageIssueException;
+import org.eclipse.lsp4j.jsonrpc.messages.NotificationMessage;
+import org.eclipse.lsp4j.jsonrpc.messages.RequestMessage;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.jsonrpc.validation.ReflectiveMessageValidator;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.google.gson.JsonObject;
+
+public class ReflectiveMessageValidatorTest {
+	
+	public static class Foo {
+		// a non exposed self reference
+		Foo self = this;
+		
+		Foo nested;
+		@NonNull String nonNullString;
+		String nullableString;
+		List<Foo> foos;
+		
+		public Foo getNested() {
+			return nested;
+		}
+		 
+		public @NonNull String getNonNullString() {
+			return nonNullString;
+		}
+		
+		public String getNullableString() {
+			return nullableString;
+		}
+		
+		public List<Foo> getFoos() {
+			return foos;
+		}
+	}
+	
+	@Test public void testNonNullViolated() {
+		ReflectiveMessageValidator validator = new ReflectiveMessageValidator();
+		
+		NotificationMessage message = new NotificationMessage();
+		message.setMethod("foo");
+		message.setParams(new Foo());
+		try {
+			validator.consume(message);
+			Assert.fail();
+		} catch (MessageIssueException e) {
+			Assert.assertEquals("The accessor 'Foo.getNonNullString()' must return a non-null value. Path: $.params.nonNullString", e.getMessage());
+		}
+	}
+	
+	@Test public void testNonNullViolated_nested() {
+		ReflectiveMessageValidator validator = new ReflectiveMessageValidator();
+		
+		NotificationMessage message = new NotificationMessage();
+		message.setMethod("foo");
+		Foo foo = new Foo();
+		foo.nonNullString = "test";
+		foo.nested = new Foo();
+		message.setParams(foo);
+		try {
+			validator.consume(message);
+			Assert.fail();
+		} catch (MessageIssueException e) {
+			Assert.assertEquals("The accessor 'Foo.getNonNullString()' must return a non-null value. Path: $.params.nested.nonNullString", e.getMessage());
+		}
+	}
+	
+	@Test public void testNoViolation() {
+		ReflectiveMessageValidator validator = new ReflectiveMessageValidator();
+		
+		NotificationMessage message = new NotificationMessage();
+		message.setMethod("foo");
+		Foo foo = new Foo();
+		foo.nonNullString = "test";
+		foo.nested = new Foo() {{
+			nonNullString = "something";
+		}};
+		message.setParams(foo);
+		validator.consume(message);
+	}
+	
+	@Test public void testRecursionViolation() {
+		ReflectiveMessageValidator validator = new ReflectiveMessageValidator();
+		
+		NotificationMessage message = new NotificationMessage();
+		message.setMethod("foo");
+		Foo foo = new Foo();
+		foo.nonNullString = "test";
+		foo.nested = foo;
+		message.setParams(foo);
+		try {
+			validator.consume(message);
+			Assert.fail();
+		} catch (MessageIssueException e) {
+			Assert.assertEquals("An element of the message has a direct or indirect reference to itself. Path: $.params.nested", e.getMessage());
+		}
+	}
+	
+	@Test public void testReflectionOnPropertiesOnly() {
+		ReflectiveMessageValidator validator = new ReflectiveMessageValidator();
+		
+		NotificationMessage message = new NotificationMessage();
+		message.setMethod("foo");
+		Foo foo = new Foo();
+		foo.nonNullString = "test";
+		foo.nested = new Foo() {{
+			nonNullString = "something";
+		}};
+		foo.foos = new ArrayList<>();
+		foo.foos.add(new Foo());
+		message.setParams(foo);
+		try {
+			validator.consume(message);
+			Assert.fail();
+		} catch (MessageIssueException e) {
+			Assert.assertEquals("The accessor 'Foo.getNonNullString()' must return a non-null value. Path: $.params.foos[0].nonNullString", e.getMessage());
+		}
+	}
+
+	@Test public void testSkipJsonElement() {
+		final AtomicBoolean result = new AtomicBoolean(false);
+		ReflectiveMessageValidator validator = new ReflectiveMessageValidator((message) -> {
+			result.set(true);
+		});
+		NotificationMessage message = new NotificationMessage();
+		message.setMethod("foo");
+		message.setParams(new JsonObject());
+		validator.consume(message);
+		Assert.assertTrue(result.get());
+	}
+	
+	@Test public void testRequestValidation() {
+		ReflectiveMessageValidator validator = new ReflectiveMessageValidator();
+		
+		RequestMessage message = new RequestMessage();
+		message.setId("1");
+		message.setParams(new Object());
+		try {
+			validator.consume(message);
+			Assert.fail();
+		} catch (MessageIssueException e) {
+			Assert.assertEquals("The accessor 'RequestMessage.getMethod()' must return a non-null value. Path: $.method", e.getMessage());
+		}
+	}
+	
+}
diff --git a/javatests/org/eclipse/lsp4j/launch/LauncherTest.java b/javatests/org/eclipse/lsp4j/launch/LauncherTest.java
new file mode 100644
index 0000000..ae83bc9
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/launch/LauncherTest.java
@@ -0,0 +1,174 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.test.launch;
+
+import java.io.IOException;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.eclipse.lsp4j.CompletionItem;
+import org.eclipse.lsp4j.CompletionItemKind;
+import org.eclipse.lsp4j.CompletionList;
+import org.eclipse.lsp4j.CompletionParams;
+import org.eclipse.lsp4j.MessageParams;
+import org.eclipse.lsp4j.MessageType;
+import org.eclipse.lsp4j.Position;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.jsonrpc.Endpoint;
+import org.eclipse.lsp4j.jsonrpc.Launcher;
+import org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.eclipse.lsp4j.jsonrpc.services.ServiceEndpoints;
+import org.eclipse.lsp4j.launch.LSPLauncher;
+import org.eclipse.lsp4j.services.LanguageClient;
+import org.eclipse.lsp4j.services.LanguageServer;
+import org.eclipse.xtext.xbase.lib.Pair;
+import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class LauncherTest {
+	
+	private static final long TIMEOUT = 2000;
+	
+	@Test public void testNotification() throws IOException {
+		MessageParams p = new MessageParams();
+		p.setMessage("Hello World");
+		p.setType(MessageType.Info);
+		
+		client.expectedNotifications.put("window/logMessage", p);
+		serverLauncher.getRemoteProxy().logMessage(p);
+		client.joinOnEmpty();
+	}
+	
+	@Test public void testRequest() throws Exception {
+		CompletionParams p = new CompletionParams();
+		p.setPosition(new Position(1,1));
+		p.setTextDocument(new TextDocumentIdentifier("test/foo.txt"));
+		
+		CompletionList result = new CompletionList();
+		result.setIsIncomplete(true);
+		result.setItems(new ArrayList<>());
+		
+		CompletionItem item = new CompletionItem();
+		item.setDetail("test");
+		item.setDocumentation("doc");
+		item.setFilterText("filter");
+		item.setInsertText("insert");
+		item.setKind(CompletionItemKind.Field);
+		result.getItems().add(item);
+		
+		server.expectedRequests.put("textDocument/completion", new Pair<>(p, result));
+		CompletableFuture<Either<List<CompletionItem>, CompletionList>> future = clientLauncher.getRemoteProxy().getTextDocumentService().completion(p);
+		Assert.assertEquals(Either.forRight(result).toString(), future.get(TIMEOUT, TimeUnit.MILLISECONDS).toString());
+		client.joinOnEmpty();
+	}
+	
+	
+	static class AssertingEndpoint implements Endpoint {
+		public Map<String, Pair<Object, Object>> expectedRequests = new LinkedHashMap<>();
+		
+		@Override
+		public CompletableFuture<?> request(String method, Object parameter) {
+			Assert.assertTrue(expectedRequests.containsKey(method));
+			Pair<Object, Object> result = expectedRequests.remove(method);
+			Assert.assertEquals(result.getKey().toString(), parameter.toString());
+			return CompletableFuture.completedFuture(result.getValue());
+		}
+
+		public Map<String, Object> expectedNotifications = new LinkedHashMap<>();
+		
+		@Override
+		public void notify(String method, Object parameter) {
+			Assert.assertTrue(expectedNotifications.containsKey(method));
+			Object object = expectedNotifications.remove(method);
+			Assert.assertEquals(object.toString(), parameter.toString());
+		}
+		
+		/**
+		 * wait max 1 sec for all expectations to be removed
+		 */
+		public void joinOnEmpty() {
+			long before = System.currentTimeMillis();
+			do {
+				if (expectedNotifications.isEmpty() && expectedNotifications.isEmpty()) {
+					return;
+				}
+				try {
+					Thread.sleep(100);
+				} catch (InterruptedException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			} while ( System.currentTimeMillis() < before + 1000);
+			Assert.fail("expectations weren't empty "+toString());
+		}
+		
+		@Override
+		public String toString() {
+			return new ToStringBuilder(this).addAllFields().toString();
+		}
+		
+	}
+
+	private AssertingEndpoint server;
+	private Launcher<LanguageClient> serverLauncher;
+	private Future<?> serverListening;
+	
+	private AssertingEndpoint client;
+	private Launcher<LanguageServer> clientLauncher;
+	private Future<?> clientListening;
+	
+	private Level logLevel;
+	
+	@Before public void setup() throws IOException {
+		PipedInputStream inClient = new PipedInputStream();
+		PipedOutputStream outClient = new PipedOutputStream();
+		PipedInputStream inServer = new PipedInputStream();
+		PipedOutputStream outServer = new PipedOutputStream();
+		
+		inClient.connect(outServer);
+		outClient.connect(inServer);
+		server = new AssertingEndpoint();
+		serverLauncher = LSPLauncher.createServerLauncher(ServiceEndpoints.toServiceObject(server, LanguageServer.class), inServer, outServer);
+		serverListening = serverLauncher.startListening();
+		
+		client = new AssertingEndpoint();
+		clientLauncher = LSPLauncher.createClientLauncher(ServiceEndpoints.toServiceObject(client, LanguageClient.class), inClient, outClient);
+		clientListening = clientLauncher.startListening();
+		
+		Logger logger = Logger.getLogger(StreamMessageProducer.class.getName());
+		logLevel = logger.getLevel();
+		logger.setLevel(Level.SEVERE);
+	}
+	
+	@After public void teardown() throws InterruptedException, ExecutionException {
+		clientListening.cancel(true);
+		serverListening.cancel(true);
+		Thread.sleep(10);
+		Logger logger = Logger.getLogger(StreamMessageProducer.class.getName());
+		logger.setLevel(logLevel);
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/performance/PerformanceMeasurement.xtend b/javatests/org/eclipse/lsp4j/performance/PerformanceMeasurement.xtend
new file mode 100644
index 0000000..0c3aaf7
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/performance/PerformanceMeasurement.xtend
@@ -0,0 +1,87 @@
+package org.eclipse.lsp4j.test.performance
+
+import com.google.gson.Gson
+import java.util.ArrayList
+import java.util.List
+import java.util.Random
+import org.eclipse.lsp4j.Location
+import org.eclipse.lsp4j.Position
+import org.eclipse.lsp4j.Range
+import org.eclipse.lsp4j.SymbolInformation
+import org.eclipse.lsp4j.SymbolKind
+import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler
+
+class PerformanceMeasurement implements Runnable {
+	
+	def static void main(String[] args) {
+		new PerformanceMeasurement().run()
+	}
+	
+	val random = new Random(0)
+	
+	override run() {
+		measureSymbolInformation()
+	}
+	
+	def void measureSymbolInformation() {
+		measure(new Measurement {
+			static val SIZE = 100_000
+			Gson gson
+			List<SymbolInformation> data
+			
+			override prepare() {
+				data = new ArrayList(SIZE)
+				for (var i = 0; i < SIZE; i++) {
+					data += new SymbolInformation => [
+						name = randomString
+						kind = SymbolKind.forValue(random.nextInt(SymbolKind.values.length) + 1)
+						location = new Location => [
+							uri = randomString
+							range = new Range => [
+								start = new Position(random.nextInt(100), random.nextInt(100))
+								end = new Position(random.nextInt(100), random.nextInt(100))
+							]
+						]
+					]
+				}
+				gson = new MessageJsonHandler(emptyMap).gson
+			}
+			
+			override run() {
+				gson.toJson(data)
+			}
+		}, 'measureSymbolInformation')
+	}
+	
+	private def measure(Measurement measurement, String name) {
+		// Warmup
+		measurement.prepare()
+		measurement.run()
+		
+		// Measure
+		val startTime = System.nanoTime
+		for (var i = 0; i < 10; i++) {
+			measurement.run()
+		}
+		val endTime = System.nanoTime
+		
+		// Display
+		val duration = (endTime - startTime) * 1e-7
+		println(name + ': ' + duration + ' ms')
+	}
+	
+	private def randomString() {
+		val length = random.nextInt(30) + 2
+		val builder = new StringBuilder(length)
+		for (var i = 0; i < length; i++) {
+			val c = (random.nextInt(75) + 48) as char
+			builder.append(c)
+		}
+		return builder.toString
+	}
+	
+	private interface Measurement extends Runnable {
+		def void prepare()
+	}
+	
+}
\ No newline at end of file
diff --git a/javatests/org/eclipse/lsp4j/services/JsonParseTest.xtend b/javatests/org/eclipse/lsp4j/services/JsonParseTest.xtend
new file mode 100644
index 0000000..bd2caa8
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/services/JsonParseTest.xtend
@@ -0,0 +1,1621 @@
+/******************************************************************************
+ * Copyright (c) 2016-2019 TypeFox and others.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.test.services
+
+import com.google.gson.JsonArray
+import com.google.gson.JsonObject
+import com.google.gson.internal.LazilyParsedNumber
+import java.util.ArrayList
+import java.util.Collection
+import java.util.HashMap
+import java.util.List
+import org.eclipse.lsp4j.ClientCapabilities
+import org.eclipse.lsp4j.CodeAction
+import org.eclipse.lsp4j.CodeActionCapabilities
+import org.eclipse.lsp4j.CodeLens
+import org.eclipse.lsp4j.CodeLensCapabilities
+import org.eclipse.lsp4j.ColorProviderCapabilities
+import org.eclipse.lsp4j.Command
+import org.eclipse.lsp4j.CompletionCapabilities
+import org.eclipse.lsp4j.CompletionItemCapabilities
+import org.eclipse.lsp4j.CompletionItemKind
+import org.eclipse.lsp4j.CompletionItemKindCapabilities
+import org.eclipse.lsp4j.CompletionParams
+import org.eclipse.lsp4j.CreateFile
+import org.eclipse.lsp4j.CreateFileOptions
+import org.eclipse.lsp4j.DefinitionCapabilities
+import org.eclipse.lsp4j.DeleteFile
+import org.eclipse.lsp4j.Diagnostic
+import org.eclipse.lsp4j.DiagnosticSeverity
+import org.eclipse.lsp4j.DidChangeTextDocumentParams
+import org.eclipse.lsp4j.DocumentFormattingParams
+import org.eclipse.lsp4j.DocumentHighlightCapabilities
+import org.eclipse.lsp4j.DocumentLinkCapabilities
+import org.eclipse.lsp4j.DocumentSymbol
+import org.eclipse.lsp4j.DocumentSymbolCapabilities
+import org.eclipse.lsp4j.FormattingCapabilities
+import org.eclipse.lsp4j.FormattingOptions
+import org.eclipse.lsp4j.Hover
+import org.eclipse.lsp4j.HoverCapabilities
+import org.eclipse.lsp4j.ImplementationCapabilities
+import org.eclipse.lsp4j.InitializeParams
+import org.eclipse.lsp4j.Location
+import org.eclipse.lsp4j.LocationLink
+import org.eclipse.lsp4j.MarkedString
+import org.eclipse.lsp4j.MarkupContent
+import org.eclipse.lsp4j.MarkupKind
+import org.eclipse.lsp4j.OnTypeFormattingCapabilities
+import org.eclipse.lsp4j.ParameterInformation
+import org.eclipse.lsp4j.Position
+import org.eclipse.lsp4j.PrepareRenameResult
+import org.eclipse.lsp4j.ProgressParams
+import org.eclipse.lsp4j.PublishDiagnosticsParams
+import org.eclipse.lsp4j.Range
+import org.eclipse.lsp4j.RangeFormattingCapabilities
+import org.eclipse.lsp4j.ReferencesCapabilities
+import org.eclipse.lsp4j.RenameCapabilities
+import org.eclipse.lsp4j.RenameFile
+import org.eclipse.lsp4j.ResourceOperation
+import org.eclipse.lsp4j.SignatureHelp
+import org.eclipse.lsp4j.SignatureHelpCapabilities
+import org.eclipse.lsp4j.SignatureInformation
+import org.eclipse.lsp4j.SignatureInformationCapabilities
+import org.eclipse.lsp4j.SymbolInformation
+import org.eclipse.lsp4j.SymbolKind
+import org.eclipse.lsp4j.SymbolKindCapabilities
+import org.eclipse.lsp4j.SynchronizationCapabilities
+import org.eclipse.lsp4j.TextDocumentClientCapabilities
+import org.eclipse.lsp4j.TextDocumentContentChangeEvent
+import org.eclipse.lsp4j.TextDocumentEdit
+import org.eclipse.lsp4j.TextDocumentIdentifier
+import org.eclipse.lsp4j.TextEdit
+import org.eclipse.lsp4j.TypeDefinitionCapabilities
+import org.eclipse.lsp4j.VersionedTextDocumentIdentifier
+import org.eclipse.lsp4j.WorkDoneProgressCancelParams
+import org.eclipse.lsp4j.WorkDoneProgressCreateParams
+import org.eclipse.lsp4j.WorkDoneProgressEnd
+import org.eclipse.lsp4j.WorkDoneProgressNotification
+import org.eclipse.lsp4j.WorkspaceClientCapabilities
+import org.eclipse.lsp4j.WorkspaceEdit
+import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler
+import org.eclipse.lsp4j.jsonrpc.messages.Either
+import org.eclipse.lsp4j.jsonrpc.messages.Message
+import org.eclipse.lsp4j.jsonrpc.messages.MessageIssue
+import org.eclipse.lsp4j.jsonrpc.messages.NotificationMessage
+import org.eclipse.lsp4j.jsonrpc.messages.RequestMessage
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseError
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseErrorCode
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage
+import org.eclipse.lsp4j.jsonrpc.messages.Tuple
+import org.eclipse.lsp4j.jsonrpc.services.ServiceEndpoints
+import org.eclipse.lsp4j.services.LanguageClient
+import org.eclipse.lsp4j.services.LanguageServer
+import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
+import org.junit.Before
+import org.junit.Test
+
+import static org.junit.Assert.*
+
+class JsonParseTest {
+
+	/**
+	 * Gson parses numbers with {@link LazilyParsedNumber}, which is not
+	 * equals-compatible with {@link Integer}.
+	 */
+	@FinalFieldsConstructor
+	private static class MyInteger extends Number {
+
+		val int value
+
+		override doubleValue() { value }
+		override floatValue() { value }
+		override intValue() { value }
+		override longValue() { value }
+
+		override equals(Object obj) {
+			if (obj instanceof Number) {
+				return value as double == obj.doubleValue
+			}
+			return false
+		}
+
+		override hashCode() {
+			Integer.hashCode(value)
+		}
+
+		override toString() {
+			Integer.toString(value)
+		}
+
+	}
+
+	MessageJsonHandler jsonHandler
+
+	@Before
+	def void setup() {
+		val methods = ServiceEndpoints.getSupportedMethods(LanguageServer)
+		val clientMethods = ServiceEndpoints.getSupportedMethods(LanguageClient)
+		val all = new HashMap
+		all.putAll(methods)
+		all.putAll(clientMethods)
+		jsonHandler = new MessageJsonHandler(all)
+	}
+
+	private def void assertParse(CharSequence json, Message expected) {
+		val actual = jsonHandler.parseMessage(json)
+		assertEquals(expected.toString, actual.toString)
+		assertEquals(expected, actual)
+	}
+
+	@Test
+	def void testCompletion() {
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": 1,
+				"method": "textDocument/completion",
+				"params": {
+					"textDocument": {
+						"uri": "file:///tmp/foo"
+					},
+					"position": {
+						"line": 4,
+						"character": 22
+					}
+				}
+			}
+		'''.assertParse(new RequestMessage => [
+			jsonrpc = "2.0"
+			id = 1
+			method = MessageMethods.DOC_COMPLETION
+			params = new CompletionParams => [
+				textDocument = new TextDocumentIdentifier => [
+					uri = "file:///tmp/foo"
+				]
+				position = new Position => [
+					line = 4
+					character = 22
+				]
+			]
+		])
+	}
+
+
+
+	@Test
+	def void testDidChange() {
+		'''
+			{
+				"jsonrpc": "2.0",
+				"method": "textDocument/didChange",
+				"params": {
+					"textDocument": {
+						"uri": "file:///tmp/foo",
+						"version": 1234
+					},
+					"contentChanges": [
+						{
+							"range": {
+								"start": {
+									"line": 7,
+									"character": 12
+								},
+								"end": {
+									"line": 8,
+									"character": 16
+								}
+							},
+							"rangeLength": 20,
+							"text": "bar"
+						}
+					]
+				}
+			}
+		'''.assertParse(new NotificationMessage => [
+			jsonrpc = "2.0"
+			method = MessageMethods.DID_CHANGE_DOC
+			params = new DidChangeTextDocumentParams => [
+				textDocument = new VersionedTextDocumentIdentifier => [
+					uri = "file:///tmp/foo"
+					version = 1234
+				]
+				contentChanges = new ArrayList => [
+					add(new TextDocumentContentChangeEvent => [
+						range = new Range => [
+							start = new Position(7, 12)
+							end = new Position(8, 16)
+						]
+						rangeLength = 20
+						text = "bar"
+					])
+				]
+			]
+		])
+	}
+
+	@Test
+	def void testPublishDiagnostics() {
+		'''
+			{
+				"jsonrpc": "2.0",
+				"method": "textDocument/publishDiagnostics",
+				"params": {
+					"uri": "file:///tmp/foo",
+					"diagnostics": [
+						{
+							"message": "Couldn\u0027t resolve reference to State \u0027bar\u0027.",
+							"range": {
+								"start": {
+									"character": 22,
+									"line": 4
+								},
+								"end": {
+									"character": 25,
+									"line": 4
+								}
+							},
+							"severity": 1
+						}
+					],
+					version: 1
+				}
+			}
+		'''.assertParse(new NotificationMessage => [
+			jsonrpc = "2.0"
+			method = MessageMethods.SHOW_DIAGNOSTICS
+			params = new PublishDiagnosticsParams => [
+				uri = "file:///tmp/foo"
+				diagnostics = new ArrayList => [
+					add(new Diagnostic => [
+						range = new Range => [
+							start = new Position(4, 22)
+							end = new Position(4, 25)
+						]
+						severity = DiagnosticSeverity.Error
+						message = "Couldn't resolve reference to State 'bar'."
+					])
+				]
+				version = 1
+			]
+		])
+	}
+
+	@Test
+	def void testDocumentSymbolResponse1() {
+		jsonHandler.methodProvider = [ id |
+			switch id {
+				case '12': MessageMethods.DOC_SYMBOL
+			}
+		]
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": "12",
+				"result": [
+					{
+						"name" : "foobar",
+						"kind" : 9,
+						"location" : {
+							"uri": "file:/baz.txt",
+							"range" : {
+								"start": {
+									"character": 22,
+									"line": 4
+								},
+								"end": {
+									"character": 25,
+									"line": 4
+								}
+							}
+						}
+					}
+				]
+			}
+		'''.assertParse(new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			result = newArrayList(Either.forLeft(
+				new SymbolInformation => [
+					name = "foobar"
+					kind = SymbolKind.Constructor
+					location = new Location => [
+						uri = "file:/baz.txt"
+						range = new Range => [
+							start = new Position(4, 22)
+							end = new Position(4, 25)
+						]
+					]
+				]
+			))
+		])
+	}
+
+	@Test
+	def void testDocumentSymbolResponse2() {
+		jsonHandler.methodProvider = [ id |
+			switch id {
+				case '12': MessageMethods.DOC_SYMBOL
+			}
+		]
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": "12",
+				"result": [
+					{
+						"name" : "foobar",
+						"kind" : 9,
+						"range" : {
+							"start": {
+								"character": 22,
+								"line": 4
+							},
+							"end": {
+								"character": 25,
+								"line": 4
+							}
+						},
+						"selectionRange": {
+							"start": {
+								"character": 22,
+								"line": 4
+							},
+							"end": {
+								"character": 25,
+								"line": 4
+							}
+						}
+					}
+				]
+			}
+		'''.assertParse(new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			result = newArrayList(Either.forRight(
+				new DocumentSymbol => [
+					name = "foobar"
+					kind = SymbolKind.Constructor
+					range = new Range => [
+						start = new Position(4, 22)
+						end = new Position(4, 25)
+					]
+					selectionRange = new Range => [
+						start = new Position(4, 22)
+						end = new Position(4, 25)
+					]
+				]
+			))
+		])
+	}
+
+	@Test
+	def void testCodeActionResponse1() {
+		jsonHandler.methodProvider = [ id |
+			switch id {
+				case '12': MessageMethods.DOC_CODE_ACTION
+			}
+		]
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": "12",
+				"result": [
+					{
+						"title": "fixme",
+						"command": "fix"
+					}
+				]
+			}
+		'''.assertParse(new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			result = newArrayList(Either.forLeft(
+				new Command => [
+					title = "fixme"
+					command = "fix"
+				]
+			))
+		])
+	}
+
+	@Test
+	def void testCodeActionResponse2() {
+		jsonHandler.methodProvider = [ id |
+			switch id {
+				case '12': MessageMethods.DOC_CODE_ACTION
+			}
+		]
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": "12",
+				"result": [
+					{
+						"title": "fixme",
+						"kind": "fix",
+						"diagnostics": [],
+						"edit": {
+							"changes": {
+								"file:test1533196529126.lspt": [
+									{
+										"range": {
+											"start": {
+												"line": 0,
+												"character": 0
+											},
+											"end": {
+												"line": 0,
+												"character": 5
+											}
+										},
+										"newText": "fixed"
+									}
+								]
+							}
+						}
+					}
+				]
+			}
+		'''.assertParse(new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			result = newArrayList(Either.forRight(
+				new CodeAction => [
+					title = "fixme"
+					kind = "fix"
+					diagnostics = newArrayList
+					edit = new WorkspaceEdit => [
+						changes.put("file:test1533196529126.lspt", newArrayList(
+							new TextEdit => [
+								range = new Range => [
+									start = new Position(0, 0)
+									end = new Position(0, 5)
+								]
+								newText = "fixed"
+							]
+						))
+					]
+				]
+			))
+		])
+	}
+
+	@Test
+	def void testCodeActionResponse3() {
+		jsonHandler.methodProvider = [ id |
+			switch id {
+				case '12': MessageMethods.DOC_CODE_ACTION
+			}
+		]
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": "12",
+				"result": [
+					{
+						"title": "fixme"
+					}
+				]
+			}
+		'''.assertParse(new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			result = newArrayList(Either.forRight(
+				new CodeAction => [
+					title = "fixme"
+				]
+			))
+		])
+	}
+
+	@Test
+	def void testPrepareRenameResponse1() {
+		jsonHandler.methodProvider = [ id |
+			switch id {
+				case '12': MessageMethods.DOC_PREPARE_RENAME
+			}
+		]
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": "12",
+				"result": {
+					"range": {
+						"start": {
+							"character": 32,
+							"line": 3
+						},
+						"end": {
+							"character": 35,
+							"line": 3
+						}
+					},
+					"placeholder": "someVar"
+				}
+			}
+		'''.assertParse(new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			result = Either.forRight(new PrepareRenameResult => [
+				range = new Range => [
+					start = new Position(3, 32)
+					end = new Position(3, 35)
+				]
+				placeholder = "someVar"
+			])
+		])
+	}
+
+	@Test
+	def void testPrepareRenameResponse2() {
+		jsonHandler.methodProvider = [ id |
+			switch id {
+				case '12': MessageMethods.DOC_PREPARE_RENAME
+			}
+		]
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": "12",
+				"result": {
+					"start": {
+						"character": 32,
+						"line": 3
+					},
+					"end": {
+						"character": 35,
+						"line": 3
+					}
+				}
+			}
+		'''.assertParse(new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			result =  Either.forLeft(new Range => [
+				start = new Position(3, 32)
+				end = new Position(3, 35)
+			])
+		])
+	}
+
+	@Test
+	def void testRenameResponse1() {
+		jsonHandler.methodProvider = [ id |
+			switch id {
+				case '12': MessageMethods.DOC_RENAME
+			}
+		]
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": "12",
+				"result": {
+					"changes": {
+						"file:///tmp/foo": [
+							{
+								"range": {
+									"start": {
+										"character": 32,
+										"line": 3
+									},
+									"end": {
+										"character": 35,
+										"line": 3
+									}
+								},
+								"newText": "foobar"
+							},
+							{
+								"range": {
+									"start": {
+										"character": 22,
+										"line": 4
+									},
+									"end": {
+										"character": 25,
+										"line": 4
+									}
+								},
+								"newText": "foobar"
+							}
+						]
+					}
+				}
+			}
+		'''.assertParse(new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			result = new WorkspaceEdit => [
+				changes = new HashMap => [
+					put("file:///tmp/foo", newArrayList(
+						new TextEdit => [
+							range = new Range => [
+								start = new Position(3, 32)
+								end = new Position(3, 35)
+							]
+							newText = "foobar"
+						],
+						new TextEdit => [
+							range = new Range => [
+								start = new Position(4, 22)
+								end = new Position(4, 25)
+							]
+							newText = "foobar"
+						]
+					))
+				]
+			]
+		])
+	}
+
+	@Test
+	def void testRenameResponse3() {
+		jsonHandler.methodProvider = [ id |
+			switch id {
+				case '12': MessageMethods.DOC_RENAME
+			}
+		]
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": "12",
+				"result": {
+					"documentChanges": [
+						{
+							"kind": "create",
+							"uri": "file:/foo.txt",
+							"options": {
+								"overwrite": true,
+								"ignoreIfExists": true
+							}
+						},
+						{
+							"kind": "delete",
+							"uri": "file:/foo.txt"
+						},
+						{
+							"kind": "rename",
+							"oldUri": "file:/foo.txt",
+							"newUri": "file:/bar.txt"
+						},
+						{
+							"textDocument": {
+								"uri": "file:/baz.txt",
+								"version": 17
+							},
+							"edits": [
+								{
+									"range": {
+										"start": {
+											"character": 32,
+											"line": 3
+										},
+										"end": {
+											"character": 35,
+											"line": 3
+										}
+									},
+									"newText": "asdfqweryxcv"
+								}
+							]
+						}
+					]
+				}
+			}
+		'''.assertParse(new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			result = new WorkspaceEdit => [
+				documentChanges = newArrayList(
+					Either.forRight((new CreateFile => [
+						uri = "file:/foo.txt"
+						options = new CreateFileOptions => [
+							overwrite = true
+							ignoreIfExists = true
+						]
+					]) as ResourceOperation),
+					Either.forRight((new DeleteFile => [
+						uri = "file:/foo.txt"
+					]) as ResourceOperation),
+					Either.forRight((new RenameFile => [
+						oldUri = "file:/foo.txt"
+						newUri = "file:/bar.txt"
+					]) as ResourceOperation),
+					Either.forLeft(new TextDocumentEdit => [
+						textDocument = new VersionedTextDocumentIdentifier("file:/baz.txt", 17)
+						edits = newArrayList(
+							new TextEdit => [
+								range = new Range => [
+									start = new Position(3, 32)
+									end = new Position(3, 35)
+								]
+								newText = "asdfqweryxcv"
+							]
+						)
+					])
+				)
+			]
+		])
+	}
+
+	@Test
+	def void testResponseError() {
+		jsonHandler.methodProvider = [ id |
+			switch id {
+				case '12':
+					'textDocument/rename'
+			}
+		]
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": "12",
+				"error": {
+					"code": -32600,
+					"message": "Could not parse request."
+				}
+			}
+		'''.assertParse(new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			error = new ResponseError => [
+				code = ResponseErrorCode.InvalidRequest
+				message = "Could not parse request."
+			]
+		])
+	}
+
+	@Test
+	def void testTelemetry() {
+		'''
+			{
+				"jsonrpc": "2.0",
+				"method": "telemetry/event",
+				"params": {
+					"foo": 12.3,
+					"bar": "qwertz"
+				}
+			}
+		'''.assertParse(new NotificationMessage => [
+			jsonrpc = "2.0"
+			method = MessageMethods.TELEMETRY_EVENT
+			params = newLinkedHashMap('foo' -> 12.3, 'bar' -> 'qwertz')
+		])
+	}
+
+	@Test
+	def void testHoverResponse1() {
+		jsonHandler.methodProvider = [ id |
+			switch id {
+				case '12': MessageMethods.DOC_HOVER
+			}
+		]
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": "12",
+				"result": {
+					"range": {
+						"start": {
+							"character": 32,
+							"line": 3
+						},
+						"end": {
+							"character": 35,
+							"line": 3
+						}
+					},
+					"contents": [
+						"foo",
+						"boo shuby doo"
+					]
+				}
+			}
+		'''.assertParse(new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			result = new Hover => [
+				range = new Range => [
+					start = new Position(3, 32)
+					end = new Position(3, 35)
+				]
+				contents = newArrayList(
+					Either.forLeft("foo"),
+					Either.forLeft("boo shuby doo")
+				)
+			]
+		])
+	}
+
+	@Test
+	def void testHoverResponse2() {
+		jsonHandler.methodProvider = [ id |
+			switch id {
+				case '12': MessageMethods.DOC_HOVER
+			}
+		]
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": "12",
+				"result": {
+					"contents": {
+						"kind": "plaintext",
+						"value": "foo"
+					}
+				}
+			}
+		'''.assertParse(new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			result = new Hover => [
+				contents = new MarkupContent => [
+					kind = "plaintext"
+					value = "foo"
+				]
+			]
+		])
+	}
+
+	@Test
+	def void testHoverResponse3() {
+		jsonHandler.methodProvider = [ id |
+			switch id {
+				case '12': MessageMethods.DOC_HOVER
+			}
+		]
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": "12",
+				"result": {
+					"contents": "foo"
+				}
+			}
+		'''.assertParse(new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			result = new Hover => [
+				contents = newArrayList(Either.forLeft("foo"))
+			]
+		])
+	}
+
+	@Test
+	def void testHoverResponse4() {
+		jsonHandler.methodProvider = [ id |
+			switch id {
+				case '12': MessageMethods.DOC_HOVER
+			}
+		]
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": "12",
+				"result": {
+					"contents": {
+						"language": "plaintext",
+						"value": "foo"
+					}
+				}
+			}
+		'''.assertParse(new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			result = new Hover => [
+				contents = newArrayList(Either.forRight(new MarkedString => [
+					language = "plaintext"
+					value = "foo"
+				]))
+			]
+		])
+	}
+
+	@Test
+	def void testCodeLensResponse() {
+		val json = '''
+			{
+				"jsonrpc": "2.0",
+				"id": "12",
+				"result": {
+					"range": {
+						"start": {
+							"character": 32,
+							"line": 3
+						},
+						"end": {
+							"character": 35,
+							"line": 3
+						}
+					},
+					"command": {
+						"title": "save",
+						"command": "saveCommand",
+						"arguments": [
+							{
+								"uri": "file:/foo",
+								"version": 5
+							}
+						]
+					},
+					"data": [
+						42,
+						"qwert",
+						{
+							"key": "value"
+						}
+					]
+				}
+			}
+		'''
+		jsonHandler.methodProvider = [ id |
+			switch id {
+				case '12': MessageMethods.DOC_CODE_LENS
+			}
+		]
+		val message = jsonHandler.parseMessage(json)
+		assertTrue("Expected a ResponseMessage", message instanceof ResponseMessage)
+		val response = message as ResponseMessage
+		assertTrue("Expected a Collection in result", response.result instanceof Collection<?>)
+		val result = response.result as Collection<?>
+		assertTrue("Expected a CodeLens in result[0]", result.head instanceof CodeLens)
+		val codeLens = result.head as CodeLens
+		assertNotNull(codeLens.command)
+		val argument = codeLens.command.arguments.head
+		assertTrue("Expected a JsonObject in command.arguments[0]", argument instanceof JsonObject)
+		assertEquals("file:/foo", (argument as JsonObject).get("uri").asString)
+		assertEquals(5, (argument as JsonObject).get("version").asInt)
+		assertTrue("Expected a JsonArray in data", codeLens.data instanceof JsonArray)
+		val data = codeLens.data as JsonArray
+		assertEquals(42, data.get(0).asInt)
+		assertEquals("qwert", data.get(1).asString)
+		assertTrue("Expected a JsonObject in data[2]", data.get(2) instanceof JsonObject)
+		assertEquals("value", (data.get(2) as JsonObject).get("key").asString)
+	}
+
+	@Test
+	def void testDeclarationResponse() {
+		jsonHandler.methodProvider = [ id |
+			switch id {
+				case '12': MessageMethods.DOC_DECLARATION
+			}
+		]
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": "12",
+				"result": [
+					{
+						"uri": "foo",
+						"range": {
+							"start": {
+								"line": 7,
+								"character": 12
+							},
+							"end": {
+								"line": 8,
+								"character": 16
+							}
+						}
+					}
+				]
+			}
+		'''.assertParse(new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			result = Either.<List<? extends Location>, List<? extends LocationLink>>forLeft(#[
+				new Location('foo', new Range(new Position(7, 12), new Position(8, 16)))
+			])
+		])
+
+	}
+
+	@Test
+	def void testItemInsteadOfListResponse() {
+		//test parse direct item without the list
+		jsonHandler.methodProvider = [ id |
+			switch id {
+				case '12': MessageMethods.DOC_DECLARATION
+			}
+		]
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": "12",
+				"result": {
+					"uri": "foo",
+					"range": {
+						"start": {
+							"line": 7,
+							"character": 12
+						},
+						"end": {
+							"line": 8,
+							"character": 16
+						}
+					}
+				}
+			}
+		'''.assertParse(new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			result = Either.<List<? extends Location>, List<? extends LocationLink>>forLeft(#[
+				new Location('foo', new Range(new Position(7, 12), new Position(8, 16)))
+			])
+		])
+	}
+
+	@Test
+	def void testDefinitionResponse1() {
+		jsonHandler.methodProvider = [ id |
+			switch id {
+				case '12': MessageMethods.DOC_DEFINITION
+			}
+		]
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": "12",
+				"result": [
+					{
+						"targetUri": "foo",
+						"targetRange": {
+							"start": {
+								"line": 7,
+								"character": 12
+							},
+							"end": {
+								"line": 8,
+								"character": 16
+							}
+						}
+					}
+				]
+			}
+		'''.assertParse(new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			result = Either.<List<? extends Location>, List<? extends LocationLink>>forRight(#[
+				new LocationLink => [
+					targetUri = 'foo'
+					targetRange = new Range(new Position(7, 12), new Position(8, 16))
+				]
+			])
+		])
+	}
+
+	@Test
+	def void testDefinitionResponse2() {
+		jsonHandler.methodProvider = [ id |
+			switch id {
+				case '12': MessageMethods.DOC_DEFINITION
+			}
+		]
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": "12",
+				"result": []
+			}
+		'''.assertParse(new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			result = Either.<List<? extends Location>, List<? extends LocationLink>>forLeft(emptyList)
+		])
+	}
+
+	@Test
+	def void testTypeDefinitionResponse() {
+		jsonHandler.methodProvider = [ id |
+			switch id {
+				case '12': MessageMethods.DOC_TYPE_DEFINITION
+			}
+		]
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": "12",
+				"result": [
+					{
+						"uri": "foo",
+						"range": {
+							"start": {
+								"line": 7,
+								"character": 12
+							},
+							"end": {
+								"line": 8,
+								"character": 16
+							}
+						}
+					}
+				]
+			}
+		'''.assertParse(new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			result = Either.<List<? extends Location>, List<? extends LocationLink>>forLeft(#[
+				new Location('foo', new Range(new Position(7, 12), new Position(8, 16)))
+			])
+		])
+	}
+
+	@Test
+	def void testImplementationResponse() {
+		jsonHandler.methodProvider = [ id |
+			switch id {
+				case '12': MessageMethods.DOC_IMPLEMENTATION
+			}
+		]
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": "12",
+				"result": [
+					{
+						"targetUri": "foo",
+						"targetRange": {
+							"start": {
+								"line": 7,
+								"character": 12
+							},
+							"end": {
+								"line": 8,
+								"character": 16
+							}
+						}
+					}
+				]
+			}
+		'''.assertParse(new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			result = Either.<List<? extends Location>, List<? extends LocationLink>>forRight(#[
+				new LocationLink => [
+					targetUri = 'foo'
+					targetRange = new Range(new Position(7, 12), new Position(8, 16))
+				]
+			])
+		])
+	}
+
+	@Test
+	def void testSignatureHelpResponse() {
+		jsonHandler.methodProvider = [ id |
+			switch id {
+				case '12': MessageMethods.DOC_SIGNATURE_HELP
+			}
+		]
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": "12",
+				"result": {
+					"signatures": [
+						{
+							"label": "Foo",
+							"parameters": [
+								{
+									"label": "label1"
+								},
+								{
+									"label": [12, 25]
+								}
+							]
+						}
+					]
+				}
+			}
+		'''.assertParse(new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			result = new SignatureHelp => [
+				signatures = #[
+					new SignatureInformation => [
+						label = "Foo"
+						parameters = #[
+							new ParameterInformation => [
+								label = Either.forLeft("label1")
+							],
+							new ParameterInformation => [
+								label = Either.forRight(Tuple.two(12, 25))
+							]
+						]
+					]
+				]
+			]
+		])
+	}
+
+	@Test
+	def void testDocumentFormatting() {
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": "12",
+				"method": "textDocument/formatting",
+				"params": {
+					"textDocument": {
+						"uri": "file:///tmp/foo"
+					},
+					"options": {
+						"insertSpaces": false,
+						"tabSize": 4,
+						"customProperty": -7
+					}
+				}
+			}
+		'''.assertParse(new RequestMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			method = MessageMethods.DOC_FORMATTING
+			params = new DocumentFormattingParams => [
+				textDocument = new TextDocumentIdentifier("file:///tmp/foo")
+				options = new FormattingOptions => [
+					insertSpaces = false
+					putNumber('tabSize', new MyInteger(4))
+					putNumber('customProperty', new MyInteger(-7))
+				]
+			]
+		])
+	}
+
+	@Test
+	def void testMessageIssue() {
+		val issue = jsonHandler.gson.fromJson('''
+			{
+				"text": "Howdy!",
+				"code": 1234,
+				"cause": {
+					"message": "Foo",
+					"cause": {
+						"message": "Bar"
+					}
+				}
+			}
+		''', MessageIssue)
+		assertEquals('Howdy!', issue.text)
+		assertEquals(1234, issue.issueCode)
+		assertEquals('Foo', issue.cause.message)
+		assertEquals('Bar', issue.cause.cause.message)
+	}
+
+	@Test
+	def void testInitialize() {
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": "1",
+				"method": "initialize",
+				"params": {
+					"rootUri": "file:///tmp/foo"
+				}
+			}
+		'''.assertParse(new RequestMessage => [
+			jsonrpc = "2.0"
+			id = "1"
+			method = MessageMethods.INITIALIZE
+			params = new InitializeParams => [
+				rootUri = "file:///tmp/foo"
+			]
+		])
+	}
+
+	@Test
+	def void testInitializeClientCapabilities() {
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": "1",
+				"method": "initialize",
+				"params": {
+					"rootUri": "file:///tmp/foo",
+					"capabilities": {
+						"textDocument": {
+							"synchronization": {
+								"dynamicRegistration": false,
+								"willSave": true,
+								"willSaveWaitUntil": false,
+								"didSave": true
+							},
+							"completion": {
+								"dynamicRegistration": false,
+								"completionItem": {
+									"snippetSupport": true,
+									"commitCharactersSupport": true,
+									"documentationFormat": ["plaintext", "markdown"]
+								},
+								"completionItemKind": {
+									"valueSet": [2, 3]
+								},
+								"contextSupport": false
+							},
+							"hover": {
+								"dynamicRegistration": false,
+								"contentFormat": ["plaintext", "markdown"]
+							},
+							"signatureHelp": {
+								"dynamicRegistration": false,
+								"signatureInformation": {
+									"documentationFormat": ["plaintext", "markdown"]
+								}
+							},
+							"references": {
+								"dynamicRegistration": false
+							},
+							"documentHighlight": {
+								"dynamicRegistration": false
+							},
+							"documentSymbol": {
+								"dynamicRegistration": false,
+								"symbolKind": {
+									valueSet: [2, 3, 4, 5]
+								}
+							},
+							"formatting": {
+								"dynamicRegistration": false
+							},
+							"rangeFormatting": {
+								"dynamicRegistration": false
+							},
+							"onTypeFormatting": {
+								"dynamicRegistration": false
+							},
+							"definition": {
+								"dynamicRegistration": false
+							},
+							"typeDefinition": {
+								"dynamicRegistration": false
+							},
+							"implementation": {
+								"dynamicRegistration": false
+							},
+							"codeAction": {
+								"dynamicRegistration": false
+							},
+							"codeLens": {
+								"dynamicRegistration": false
+							},
+							"documentLink": {
+								"dynamicRegistration": false
+							},
+							"colorProvider": {
+								"dynamicRegistration": false
+							},
+							"rename": {
+								"dynamicRegistration": false
+							}
+						},
+						"workspace": {}
+					}
+				}
+			}
+		'''.assertParse(new RequestMessage => [
+			jsonrpc = "2.0"
+			id = "1"
+			method = MessageMethods.INITIALIZE
+			params = new InitializeParams => [
+				rootUri = "file:///tmp/foo"
+				capabilities = new ClientCapabilities => [
+					textDocument = new TextDocumentClientCapabilities => [
+						synchronization = new SynchronizationCapabilities => [
+							dynamicRegistration = false
+							willSave= true
+							willSaveWaitUntil= false
+							didSave = true
+						]
+						completion = new CompletionCapabilities => [
+							dynamicRegistration = false
+							completionItem = new CompletionItemCapabilities => [
+								snippetSupport = true
+								commitCharactersSupport = true
+								documentationFormat = #[MarkupKind.PLAINTEXT, MarkupKind.MARKDOWN]
+							]
+							completionItemKind = new CompletionItemKindCapabilities => [
+								valueSet = #[CompletionItemKind.Method, CompletionItemKind.Function]
+							]
+							contextSupport = false
+						]
+						hover = new HoverCapabilities => [
+							dynamicRegistration = false
+							contentFormat = #[MarkupKind.PLAINTEXT, MarkupKind.MARKDOWN]
+						]
+						signatureHelp = new SignatureHelpCapabilities => [
+							dynamicRegistration = false
+							signatureInformation = new SignatureInformationCapabilities => [
+								documentationFormat = #[MarkupKind.PLAINTEXT, MarkupKind.MARKDOWN]
+							]
+						]
+						references = new ReferencesCapabilities => [
+							dynamicRegistration = false
+						]
+						documentHighlight = new DocumentHighlightCapabilities => [
+							dynamicRegistration = false
+						]
+						documentSymbol = new DocumentSymbolCapabilities => [
+							dynamicRegistration = false
+							symbolKind = new SymbolKindCapabilities => [
+								valueSet = #[SymbolKind.Module, SymbolKind.Namespace, SymbolKind.Package, SymbolKind.Class]
+							]
+						]
+						formatting = new FormattingCapabilities => [
+							dynamicRegistration = false
+						]
+						rangeFormatting = new RangeFormattingCapabilities => [
+							dynamicRegistration = false
+						]
+						onTypeFormatting = new OnTypeFormattingCapabilities => [
+							dynamicRegistration = false
+						]
+						definition= new DefinitionCapabilities => [
+							dynamicRegistration = false
+						]
+						typeDefinition= new TypeDefinitionCapabilities => [
+							dynamicRegistration = false
+						]
+						implementation= new ImplementationCapabilities => [
+							dynamicRegistration = false
+						]
+						codeAction = new CodeActionCapabilities => [
+							dynamicRegistration = false
+						]
+						codeLens= new CodeLensCapabilities => [
+							dynamicRegistration = false
+						]
+						documentLink= new DocumentLinkCapabilities => [
+							dynamicRegistration = false
+						]
+						colorProvider = new ColorProviderCapabilities => [
+							dynamicRegistration = false
+						]
+						rename = new RenameCapabilities => [
+							dynamicRegistration = false
+						]
+					]
+					workspace = new WorkspaceClientCapabilities
+				]
+			]
+		])
+	}
+
+
+
+	@Test
+	def void testProgressCreate() {
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": 1,
+				"method": "window/workDoneProgress/create",
+				"params": {
+					"token": "progress-token"
+				}
+			}
+		'''.assertParse(new RequestMessage => [
+			jsonrpc = "2.0"
+			id = 1
+			method = MessageMethods.PROGRESS_CREATE
+			params = new WorkDoneProgressCreateParams => [
+				token = Either.forLeft("progress-token")
+			]
+		])
+
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": 1,
+				"method": "window/workDoneProgress/create",
+				"params": {
+					"token": 1234
+				}
+			}
+		'''.assertParse(new RequestMessage => [
+			jsonrpc = "2.0"
+			id = 1
+			method = MessageMethods.PROGRESS_CREATE
+			params = new WorkDoneProgressCreateParams => [
+				token = Either.forRight(1234)
+			]
+		])
+	}
+
+	@Test
+	def void testProgressCancel() {
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": 1,
+				"method": "window/workDoneProgress/cancel",
+				"params": {
+					"token": "progress-token"
+				}
+			}
+		'''.assertParse(new RequestMessage => [
+			jsonrpc = "2.0"
+			id = 1
+			method = MessageMethods.PROGRESS_CANCEL
+			params = new WorkDoneProgressCancelParams => [
+				token = Either.forLeft("progress-token")
+			]
+		])
+
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": 1,
+				"method": "window/workDoneProgress/cancel",
+				"params": {
+					"token": 1234
+				}
+			}
+		'''.assertParse(new RequestMessage => [
+			jsonrpc = "2.0"
+			id = 1
+			method = MessageMethods.PROGRESS_CANCEL
+			params = new WorkDoneProgressCancelParams => [
+				token = Either.forRight(1234)
+			]
+		])
+	}
+
+	@Test
+	def void testProgressNotify() {
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": 1,
+				"method": "$/progress",
+				"params": {
+					"token": "progress-token",
+					"value": {
+						"kind": "end",
+						"message": "message"
+					}
+				}
+			}
+		'''.assertParse(new RequestMessage => [
+			jsonrpc = "2.0"
+			id = 1
+			method = MessageMethods.PROGRESS_NOTIFY
+			params = new ProgressParams => [
+				token = Either.forLeft("progress-token")
+				value = Either.<WorkDoneProgressNotification, Object>forLeft(new WorkDoneProgressEnd => [
+					message = "message"
+				])
+			]
+		])
+
+		'''
+			{
+				"jsonrpc": "2.0",
+				"id": 1,
+				"method": "$/progress",
+				"params": {
+					"token": 1234,
+					"value": {
+						"foo": "bar"
+					}
+				}
+			}
+		'''.assertParse(new RequestMessage => [
+			jsonrpc = "2.0"
+			id = 1
+			method = MessageMethods.PROGRESS_NOTIFY
+			params = new ProgressParams => [
+				token = Either.forRight(1234)
+				value = Either.<WorkDoneProgressNotification, Object>forRight(new JsonObject => [
+					addProperty("foo", "bar")
+				])
+			]
+		])
+	}
+}
diff --git a/javatests/org/eclipse/lsp4j/services/JsonSerializeTest.xtend b/javatests/org/eclipse/lsp4j/services/JsonSerializeTest.xtend
new file mode 100644
index 0000000..2f94e14
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/services/JsonSerializeTest.xtend
@@ -0,0 +1,932 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.test.services
+
+import com.google.gson.JsonObject
+import java.util.ArrayList
+import java.util.HashMap
+import org.eclipse.lsp4j.ClientCapabilities
+import org.eclipse.lsp4j.CodeActionCapabilities
+import org.eclipse.lsp4j.CodeLens
+import org.eclipse.lsp4j.CodeLensCapabilities
+import org.eclipse.lsp4j.ColorProviderCapabilities
+import org.eclipse.lsp4j.Command
+import org.eclipse.lsp4j.CompletionCapabilities
+import org.eclipse.lsp4j.CompletionItem
+import org.eclipse.lsp4j.CompletionItemCapabilities
+import org.eclipse.lsp4j.CompletionItemKind
+import org.eclipse.lsp4j.CompletionItemKindCapabilities
+import org.eclipse.lsp4j.CompletionList
+import org.eclipse.lsp4j.DefinitionCapabilities
+import org.eclipse.lsp4j.Diagnostic
+import org.eclipse.lsp4j.DiagnosticSeverity
+import org.eclipse.lsp4j.DidChangeTextDocumentParams
+import org.eclipse.lsp4j.DocumentFormattingParams
+import org.eclipse.lsp4j.DocumentHighlightCapabilities
+import org.eclipse.lsp4j.DocumentLinkCapabilities
+import org.eclipse.lsp4j.DocumentSymbolCapabilities
+import org.eclipse.lsp4j.FormattingCapabilities
+import org.eclipse.lsp4j.FormattingOptions
+import org.eclipse.lsp4j.Hover
+import org.eclipse.lsp4j.HoverCapabilities
+import org.eclipse.lsp4j.ImplementationCapabilities
+import org.eclipse.lsp4j.InitializeParams
+import org.eclipse.lsp4j.InitializeResult
+import org.eclipse.lsp4j.MarkupContent
+import org.eclipse.lsp4j.MarkupKind
+import org.eclipse.lsp4j.OnTypeFormattingCapabilities
+import org.eclipse.lsp4j.Position
+import org.eclipse.lsp4j.ProgressParams
+import org.eclipse.lsp4j.PublishDiagnosticsParams
+import org.eclipse.lsp4j.Range
+import org.eclipse.lsp4j.RangeFormattingCapabilities
+import org.eclipse.lsp4j.ReferencesCapabilities
+import org.eclipse.lsp4j.RenameCapabilities
+import org.eclipse.lsp4j.ServerCapabilities
+import org.eclipse.lsp4j.SignatureHelpCapabilities
+import org.eclipse.lsp4j.SignatureInformationCapabilities
+import org.eclipse.lsp4j.SymbolKind
+import org.eclipse.lsp4j.SymbolKindCapabilities
+import org.eclipse.lsp4j.SynchronizationCapabilities
+import org.eclipse.lsp4j.TextDocumentClientCapabilities
+import org.eclipse.lsp4j.TextDocumentContentChangeEvent
+import org.eclipse.lsp4j.TextDocumentIdentifier
+import org.eclipse.lsp4j.TextDocumentPositionParams
+import org.eclipse.lsp4j.TextEdit
+import org.eclipse.lsp4j.TypeDefinitionCapabilities
+import org.eclipse.lsp4j.VersionedTextDocumentIdentifier
+import org.eclipse.lsp4j.WorkDoneProgressCancelParams
+import org.eclipse.lsp4j.WorkDoneProgressCreateParams
+import org.eclipse.lsp4j.WorkDoneProgressEnd
+import org.eclipse.lsp4j.WorkDoneProgressNotification
+import org.eclipse.lsp4j.WorkspaceClientCapabilities
+import org.eclipse.lsp4j.WorkspaceEdit
+import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler
+import org.eclipse.lsp4j.jsonrpc.messages.Either
+import org.eclipse.lsp4j.jsonrpc.messages.Message
+import org.eclipse.lsp4j.jsonrpc.messages.NotificationMessage
+import org.eclipse.lsp4j.jsonrpc.messages.RequestMessage
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseError
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseErrorCode
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage
+import org.eclipse.lsp4j.jsonrpc.services.ServiceEndpoints
+import org.eclipse.lsp4j.services.LanguageServer
+import org.junit.Before
+import org.junit.Test
+
+import static org.junit.Assert.*
+
+import static extension org.eclipse.lsp4j.test.services.LineEndings.*
+
+class JsonSerializeTest {
+	
+	MessageJsonHandler jsonHandler
+	
+	@Before
+	def void setup() {
+		val methods = ServiceEndpoints.getSupportedMethods(LanguageServer)
+		jsonHandler = new MessageJsonHandler(methods) [
+			setPrettyPrinting()
+		]
+	}
+	
+	private def assertSerialize(Message message, CharSequence expected) {
+		assertEquals(expected.toString.trim, jsonHandler.serialize(message).toSystemLineEndings)
+	}
+	
+	@Test
+	def void testCompletion() {
+		val message = new RequestMessage => [
+			jsonrpc = "2.0"
+			id = "1"
+			method = MessageMethods.DOC_COMPLETION
+			params = new TextDocumentPositionParams => [
+				textDocument = new TextDocumentIdentifier("file:///tmp/foo")
+				position = new Position(4, 22)
+			]
+		]
+		message.assertSerialize('''
+			{
+			  "jsonrpc": "2.0",
+			  "id": "1",
+			  "method": "textDocument/completion",
+			  "params": {
+			    "textDocument": {
+			      "uri": "file:///tmp/foo"
+			    },
+			    "position": {
+			      "line": 4,
+			      "character": 22
+			    }
+			  }
+			}
+		''')
+	}
+
+	@Test
+	def void testInit() {
+		val message = new RequestMessage => [
+			jsonrpc = "2.0"
+			id = "1"
+			method = MessageMethods.INITIALIZE
+			params = new InitializeParams => [
+				rootUri = "file:///tmp/foo"
+			]
+		]
+		message.assertSerialize('''
+			{
+			  "jsonrpc": "2.0",
+			  "id": "1",
+			  "method": "initialize",
+			  "params": {
+			    "processId": null,
+			    "rootUri": "file:///tmp/foo"
+			  }
+			}
+		''')
+	}
+	
+	@Test
+	def void testInitClientCapabilities() {
+		val message = new RequestMessage => [
+			jsonrpc = "2.0"
+			id = "1"
+			method = MessageMethods.INITIALIZE
+			params = new InitializeParams => [
+				rootUri = "file:///tmp/foo"
+				capabilities = new ClientCapabilities => [
+					textDocument = new TextDocumentClientCapabilities => [
+						synchronization = new SynchronizationCapabilities => [
+							dynamicRegistration = false
+							willSave= true
+							willSaveWaitUntil= false
+							didSave = true
+						]
+						completion = new CompletionCapabilities => [
+							dynamicRegistration = false
+							completionItem = new CompletionItemCapabilities => [
+								snippetSupport = true
+								commitCharactersSupport = true
+								documentationFormat = #[MarkupKind.PLAINTEXT, MarkupKind.MARKDOWN]
+							]
+							completionItemKind = new CompletionItemKindCapabilities => [
+								valueSet = #[CompletionItemKind.Method, CompletionItemKind.Function]
+							]
+							contextSupport = false
+						]
+						hover = new HoverCapabilities => [
+							dynamicRegistration = false
+							contentFormat = #[MarkupKind.PLAINTEXT, MarkupKind.MARKDOWN]
+						]
+						signatureHelp = new SignatureHelpCapabilities => [
+							dynamicRegistration = false
+							signatureInformation = new SignatureInformationCapabilities => [
+								documentationFormat = #[MarkupKind.PLAINTEXT, MarkupKind.MARKDOWN]
+							]
+						]
+						references = new ReferencesCapabilities => [
+							dynamicRegistration = false
+						]
+						documentHighlight = new DocumentHighlightCapabilities => [
+							dynamicRegistration = false
+						]
+						documentSymbol = new DocumentSymbolCapabilities => [
+							dynamicRegistration = false
+							symbolKind = new SymbolKindCapabilities => [
+								valueSet = #[SymbolKind.Module, SymbolKind.Namespace, SymbolKind.Package, SymbolKind.Class]
+							]
+						]
+						formatting = new FormattingCapabilities => [
+							dynamicRegistration = false
+						]
+						rangeFormatting = new RangeFormattingCapabilities => [
+							dynamicRegistration = false
+						]
+						onTypeFormatting = new OnTypeFormattingCapabilities => [
+							dynamicRegistration = false
+						]
+						definition= new DefinitionCapabilities => [
+							dynamicRegistration = false
+						]
+						typeDefinition= new TypeDefinitionCapabilities => [
+							dynamicRegistration = false
+						]
+						implementation= new ImplementationCapabilities => [
+							dynamicRegistration = false
+						]
+						codeAction = new CodeActionCapabilities => [
+							dynamicRegistration = false
+						]
+						codeLens= new CodeLensCapabilities => [
+							dynamicRegistration = false
+						]
+						documentLink= new DocumentLinkCapabilities => [
+							dynamicRegistration = false
+						]
+						colorProvider = new ColorProviderCapabilities => [
+							dynamicRegistration = false
+						]
+						rename = new RenameCapabilities => [
+							dynamicRegistration = false
+						]
+					]
+					workspace = new WorkspaceClientCapabilities
+				]
+			]
+		]
+		message.assertSerialize('''
+			{
+			  "jsonrpc": "2.0",
+			  "id": "1",
+			  "method": "initialize",
+			  "params": {
+			    "processId": null,
+			    "rootUri": "file:///tmp/foo",
+			    "capabilities": {
+			      "workspace": {},
+			      "textDocument": {
+			        "synchronization": {
+			          "willSave": true,
+			          "willSaveWaitUntil": false,
+			          "didSave": true,
+			          "dynamicRegistration": false
+			        },
+			        "completion": {
+			          "completionItem": {
+			            "snippetSupport": true,
+			            "commitCharactersSupport": true,
+			            "documentationFormat": [
+			              "plaintext",
+			              "markdown"
+			            ]
+			          },
+			          "completionItemKind": {
+			            "valueSet": [
+			              2,
+			              3
+			            ]
+			          },
+			          "contextSupport": false,
+			          "dynamicRegistration": false
+			        },
+			        "hover": {
+			          "contentFormat": [
+			            "plaintext",
+			            "markdown"
+			          ],
+			          "dynamicRegistration": false
+			        },
+			        "signatureHelp": {
+			          "signatureInformation": {
+			            "documentationFormat": [
+			              "plaintext",
+			              "markdown"
+			            ]
+			          },
+			          "dynamicRegistration": false
+			        },
+			        "references": {
+			          "dynamicRegistration": false
+			        },
+			        "documentHighlight": {
+			          "dynamicRegistration": false
+			        },
+			        "documentSymbol": {
+			          "symbolKind": {
+			            "valueSet": [
+			              2,
+			              3,
+			              4,
+			              5
+			            ]
+			          },
+			          "dynamicRegistration": false
+			        },
+			        "formatting": {
+			          "dynamicRegistration": false
+			        },
+			        "rangeFormatting": {
+			          "dynamicRegistration": false
+			        },
+			        "onTypeFormatting": {
+			          "dynamicRegistration": false
+			        },
+			        "definition": {
+			          "dynamicRegistration": false
+			        },
+			        "typeDefinition": {
+			          "dynamicRegistration": false
+			        },
+			        "implementation": {
+			          "dynamicRegistration": false
+			        },
+			        "codeAction": {
+			          "dynamicRegistration": false
+			        },
+			        "codeLens": {
+			          "dynamicRegistration": false
+			        },
+			        "documentLink": {
+			          "dynamicRegistration": false
+			        },
+			        "colorProvider": {
+			          "dynamicRegistration": false
+			        },
+			        "rename": {
+			          "dynamicRegistration": false
+			        }
+			      }
+			    }
+			  }
+			}
+		''')
+	}
+	
+	@Test
+	def void testInitResponse() {
+		val message = new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = 12
+			result = new InitializeResult => [
+				capabilities = new ServerCapabilities
+			]
+		]
+		message.assertSerialize('''
+			{
+			  "jsonrpc": "2.0",
+			  "id": 12,
+			  "result": {
+			    "capabilities": {}
+			  }
+			}
+		''')
+	}
+	
+	@Test
+	def void testDidChange() {
+		val message = new NotificationMessage => [
+			jsonrpc = "2.0"
+			method = MessageMethods.DID_CHANGE_DOC
+			params = new DidChangeTextDocumentParams => [
+				textDocument = new VersionedTextDocumentIdentifier => [
+					uri = "file:///tmp/foo"
+				]
+				contentChanges = new ArrayList => [
+					add(new TextDocumentContentChangeEvent => [
+						range = new Range => [
+							start = new Position(7, 12)
+							end = new Position(8, 16)
+						]
+						rangeLength = 20
+						text = "bar"
+					])
+				]
+			]
+		]
+		message.assertSerialize('''
+			{
+			  "jsonrpc": "2.0",
+			  "method": "textDocument/didChange",
+			  "params": {
+			    "textDocument": {
+			      "version": null,
+			      "uri": "file:///tmp/foo"
+			    },
+			    "contentChanges": [
+			      {
+			        "range": {
+			          "start": {
+			            "line": 7,
+			            "character": 12
+			          },
+			          "end": {
+			            "line": 8,
+			            "character": 16
+			          }
+			        },
+			        "rangeLength": 20,
+			        "text": "bar"
+			      }
+			    ]
+			  }
+			}
+		''')
+	}
+	
+	@Test
+	def void testPublishDiagnostics() {
+		val message = new NotificationMessage => [
+			jsonrpc = "2.0"
+			method = MessageMethods.SHOW_DIAGNOSTICS
+			params = new PublishDiagnosticsParams => [
+				uri = "file:///tmp/foo"
+				diagnostics = new ArrayList => [
+					add(new Diagnostic => [
+						range = new Range => [
+							start = new Position(4, 22)
+							end = new Position(4, 25)
+						]
+						severity = DiagnosticSeverity.Error
+						message = "Couldn't resolve reference to State 'bar'."
+					])
+				]
+				version = 1
+			]
+		]
+		message.assertSerialize('''
+			{
+			  "jsonrpc": "2.0",
+			  "method": "textDocument/publishDiagnostics",
+			  "params": {
+			    "uri": "file:///tmp/foo",
+			    "diagnostics": [
+			      {
+			        "range": {
+			          "start": {
+			            "line": 4,
+			            "character": 22
+			          },
+			          "end": {
+			            "line": 4,
+			            "character": 25
+			          }
+			        },
+			        "severity": 1,
+			        "message": "Couldn\u0027t resolve reference to State \u0027bar\u0027."
+			      }
+			    ],
+			    "version": 1
+			  }
+			}
+		''')
+	}
+	
+    @Test
+	def void testRenameResponse() {
+		val message = new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			result = new WorkspaceEdit => [
+				changes = new HashMap => [
+					put("file:///tmp/foo", newArrayList(
+						new TextEdit => [
+							range = new Range => [
+								start = new Position(3, 32)
+								end = new Position(3, 35)
+							]
+							newText = "foobar"
+						],
+						new TextEdit => [
+							range = new Range => [
+								start = new Position(4, 22)
+								end = new Position(4, 25)
+							]
+							newText = "foobar"
+						]
+					))
+				]
+			]
+		]
+		message.assertSerialize('''
+			{
+			  "jsonrpc": "2.0",
+			  "id": "12",
+			  "result": {
+			    "changes": {
+			      "file:///tmp/foo": [
+			        {
+			          "range": {
+			            "start": {
+			              "line": 3,
+			              "character": 32
+			            },
+			            "end": {
+			              "line": 3,
+			              "character": 35
+			            }
+			          },
+			          "newText": "foobar"
+			        },
+			        {
+			          "range": {
+			            "start": {
+			              "line": 4,
+			              "character": 22
+			            },
+			            "end": {
+			              "line": 4,
+			              "character": 25
+			            }
+			          },
+			          "newText": "foobar"
+			        }
+			      ]
+			    }
+			  }
+			}
+		''')
+	}
+
+	@Test
+	def void testHoverResponse1() {
+		val message = new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			result = new Hover => [
+				range = new Range => [
+					start = new Position(3, 32)
+					end = new Position(3, 35)
+				]
+				contents = newArrayList(
+					Either.forLeft("foo"),
+					Either.forLeft("boo shuby doo")
+				)
+			]
+		]
+		message.assertSerialize('''
+			{
+			  "jsonrpc": "2.0",
+			  "id": "12",
+			  "result": {
+			    "contents": [
+			      "foo",
+			      "boo shuby doo"
+			    ],
+			    "range": {
+			      "start": {
+			        "line": 3,
+			        "character": 32
+			      },
+			      "end": {
+			        "line": 3,
+			        "character": 35
+			      }
+			    }
+			  }
+			}
+		''')
+	}
+
+	@Test
+	def void testHoverResponse2() {
+		val message = new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			result = new Hover => [
+				contents = new MarkupContent => [
+					kind = "plaintext"
+					value = "foo"
+				]
+			]
+		]
+		message.assertSerialize('''
+			{
+			  "jsonrpc": "2.0",
+			  "id": "12",
+			  "result": {
+			    "contents": {
+			      "kind": "plaintext",
+			      "value": "foo"
+			    }
+			  }
+			}
+		''')
+	}
+    
+	@Test
+	def void testCodeLensResponse() {
+		val message = new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			result = new CodeLens => [
+				range = new Range => [
+					start = new Position(3, 32)
+					end = new Position(3, 35)
+				]
+				command = new Command => [
+					title = 'save'
+					command = 'saveCommand'
+					arguments = <Object>newArrayList(
+						new JsonObject => [
+							addProperty('uri', 'file:/foo')
+							addProperty('version', 5)
+						]
+					)
+				]
+				data = <Object>newArrayList(
+					42,
+					'qwert',
+					new JsonObject => [
+						addProperty('key', 'value')
+					]
+				)
+			]
+		]
+		message.assertSerialize('''
+			{
+			  "jsonrpc": "2.0",
+			  "id": "12",
+			  "result": {
+			    "range": {
+			      "start": {
+			        "line": 3,
+			        "character": 32
+			      },
+			      "end": {
+			        "line": 3,
+			        "character": 35
+			      }
+			    },
+			    "command": {
+			      "title": "save",
+			      "command": "saveCommand",
+			      "arguments": [
+			        {
+			          "uri": "file:/foo",
+			          "version": 5
+			        }
+			      ]
+			    },
+			    "data": [
+			      42,
+			      "qwert",
+			      {
+			        "key": "value"
+			      }
+			    ]
+			  }
+			}
+		''')
+	}
+    
+    @Test
+    def void testResponseError() {
+        val message = new ResponseMessage => [
+            jsonrpc = "2.0"
+            id = "12"
+            error = new ResponseError => [
+                code = ResponseErrorCode.InvalidRequest
+                message = "Could not parse request."
+            ]
+        ]
+        message.assertSerialize('''
+            {
+              "jsonrpc": "2.0",
+              "id": "12",
+              "error": {
+                "code": -32600,
+                "message": "Could not parse request."
+              }
+            }
+        ''')
+    }
+        
+	@Test
+	def void testCompletionResponse() {
+		val message = new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			result = new CompletionList => [
+				isIncomplete = true
+				items = #[
+					new CompletionItem => [
+						label = 'foo'	
+					]
+				]
+			]
+		]
+		message.assertSerialize('''
+			{
+			  "jsonrpc": "2.0",
+			  "id": "12",
+			  "result": {
+			    "isIncomplete": true,
+			    "items": [
+			      {
+			        "label": "foo"
+			      }
+			    ]
+			  }
+			}
+		''')
+	}
+	
+	@Test
+	def void testDocumentFormatting() {
+		val message = new RequestMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+			method = MessageMethods.DOC_FORMATTING
+			params = new DocumentFormattingParams => [
+				textDocument = new TextDocumentIdentifier("file:///tmp/foo")
+				options = new FormattingOptions => [
+					tabSize = 4
+					insertSpaces = false
+				]
+				options.putNumber('customProperty', -7)
+			]
+		]
+		message.assertSerialize('''
+			{
+			  "jsonrpc": "2.0",
+			  "id": "12",
+			  "method": "textDocument/formatting",
+			  "params": {
+			    "textDocument": {
+			      "uri": "file:///tmp/foo"
+			    },
+			    "options": {
+			      "tabSize": 4,
+			      "insertSpaces": false,
+			      "customProperty": -7
+			    }
+			  }
+			}
+		''')
+	}
+	
+	@Test
+	def void testTelemetry() {
+		val message = new NotificationMessage => [
+			jsonrpc = "2.0"
+			method = MessageMethods.TELEMETRY_EVENT
+			params = new TestObject
+		]
+		message.assertSerialize('''
+			{
+			  "jsonrpc": "2.0",
+			  "method": "telemetry/event",
+			  "params": {
+			    "foo": 12.3,
+			    "bar": "qwertz"
+			  }
+			}
+		''')
+	}
+	
+	private static class TestObject {
+		package double foo = 12.3
+		package String bar = "qwertz"
+	}
+        
+	@Test
+	def void testNullResponse() {
+		val message = new ResponseMessage => [
+			jsonrpc = "2.0"
+			id = "12"
+		]
+		message.assertSerialize('''
+			{
+			  "jsonrpc": "2.0",
+			  "id": "12",
+			  "result": null
+			}
+		''')
+	}
+	
+	@Test
+	def void testProgressCreate() {
+		val message = new RequestMessage => [
+			jsonrpc = "2.0"
+			id = "1"
+			method = MessageMethods.PROGRESS_CREATE
+			params = new WorkDoneProgressCreateParams => [
+				token = Either.forLeft("progress-token")
+			]
+		]
+		message.assertSerialize('''
+			{
+			  "jsonrpc": "2.0",
+			  "id": "1",
+			  "method": "window/workDoneProgress/create",
+			  "params": {
+			    "token": "progress-token"
+			  }
+			}
+		''')
+		
+		val message2 = new RequestMessage => [
+			jsonrpc = "2.0"
+			id = "1"
+			method = MessageMethods.PROGRESS_CREATE
+			params = new WorkDoneProgressCreateParams => [
+				token = Either.forRight(1234)
+			]
+		]
+		message2.assertSerialize('''
+			{
+			  "jsonrpc": "2.0",
+			  "id": "1",
+			  "method": "window/workDoneProgress/create",
+			  "params": {
+			    "token": 1234
+			  }
+			}
+		''')
+	}
+	
+	@Test
+	def void testProgressCancel() {
+		val message = new RequestMessage => [
+			jsonrpc = "2.0"
+			id = "1"
+			method = MessageMethods.PROGRESS_CANCEL
+			params = new WorkDoneProgressCancelParams => [
+				token = Either.forLeft("progress-token")
+			]
+		]
+		message.assertSerialize('''
+			{
+			  "jsonrpc": "2.0",
+			  "id": "1",
+			  "method": "window/workDoneProgress/cancel",
+			  "params": {
+			    "token": "progress-token"
+			  }
+			}
+		''')
+		
+		val message2 = new RequestMessage => [
+			jsonrpc = "2.0"
+			id = "1"
+			method = MessageMethods.PROGRESS_CANCEL
+			params = new WorkDoneProgressCancelParams => [
+				token = Either.forRight(1234)
+			]
+		]
+		message2.assertSerialize('''
+			{
+			  "jsonrpc": "2.0",
+			  "id": "1",
+			  "method": "window/workDoneProgress/cancel",
+			  "params": {
+			    "token": 1234
+			  }
+			}
+		''')
+	}
+	
+	@Test
+	def void testProgressNotify() {
+		val message = new RequestMessage => [
+			jsonrpc = "2.0"
+			id = "1"
+			method = MessageMethods.PROGRESS_NOTIFY
+			params = new ProgressParams => [
+				token = Either.forLeft("progress-token")
+				value = Either.<WorkDoneProgressNotification, Object>forLeft(new WorkDoneProgressEnd => [
+					message = "message"
+				])
+			]
+		]
+		message.assertSerialize('''
+			{
+			  "jsonrpc": "2.0",
+			  "id": "1",
+			  "method": "$/progress",
+			  "params": {
+			    "token": "progress-token",
+			    "value": {
+			      "kind": "end",
+			      "message": "message"
+			    }
+			  }
+			}
+		''')
+		
+		val message2 = new RequestMessage => [
+			jsonrpc = "2.0"
+			id = "1"
+			method = MessageMethods.PROGRESS_NOTIFY
+			params = new ProgressParams => [
+				token = Either.forRight(1234)
+				value = Either.<WorkDoneProgressNotification, Object>forRight(new JsonObject => [
+					addProperty("foo", "bar")
+				])
+			]
+		]
+		message2.assertSerialize('''
+			{
+			  "jsonrpc": "2.0",
+			  "id": "1",
+			  "method": "$/progress",
+			  "params": {
+			    "token": 1234,
+			    "value": {
+			      "foo": "bar"
+			    }
+			  }
+			}
+		''')
+	}
+	
+}
diff --git a/javatests/org/eclipse/lsp4j/services/LineEndings.xtend b/javatests/org/eclipse/lsp4j/services/LineEndings.xtend
new file mode 100644
index 0000000..3b0640b
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/services/LineEndings.xtend
@@ -0,0 +1,27 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.test.services
+
+import java.util.regex.Pattern
+import org.eclipse.xtend2.lib.StringConcatenation
+
+final class LineEndings {
+	
+	static val LINE_ENDING_PAT = Pattern.compile('\\r?\\n')
+	
+	private new() {}
+	
+	static def toSystemLineEndings(CharSequence s) {
+		LINE_ENDING_PAT.matcher(s).replaceAll(StringConcatenation.DEFAULT_LINE_DELIMITER)
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/services/MessageMethods.xtend b/javatests/org/eclipse/lsp4j/services/MessageMethods.xtend
new file mode 100644
index 0000000..3ee65cd
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/services/MessageMethods.xtend
@@ -0,0 +1,56 @@
+/******************************************************************************
+ * Copyright (c) 2016-2019 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.test.services
+
+interface MessageMethods {
+	
+	public static val INITIALIZE = 'initialize'
+	public static val SHUTDOWN = 'shutdown'
+	public static val EXIT = 'exit'
+	public static val DOC_COMPLETION = 'textDocument/completion'
+	public static val RESOLVE_COMPLETION = 'completionItem/resolve'
+	public static val DOC_HOVER = 'textDocument/hover'
+	public static val DOC_SIGNATURE_HELP = 'textDocument/signatureHelp'
+	public static val DOC_DECLARATION = 'textDocument/declaration'
+	public static val DOC_DEFINITION = 'textDocument/definition'
+	public static val DOC_TYPE_DEFINITION = 'textDocument/typeDefinition'
+	public static val DOC_IMPLEMENTATION = 'textDocument/implementation'
+	public static val DOC_HIGHLIGHT = 'textDocument/documentHighlight'
+	public static val DOC_REFERENCES = 'textDocument/references'
+	public static val DOC_SYMBOL = 'textDocument/documentSymbol'
+	public static val DOC_CODE_ACTION = 'textDocument/codeAction'
+	public static val DOC_CODE_LENS = 'textDocument/codeLens'
+	public static val RESOLVE_CODE_LENS = 'codeLens/resolve'
+	public static val DOC_FOLDING_RANGE = 'textDocument/foldingRange'
+	public static val DOC_FORMATTING = 'textDocument/formatting'
+	public static val DOC_RANGE_FORMATTING = 'textDocument/rangeFormatting'
+	public static val DOC_TYPE_FORMATTING = 'textDocument/onTypeFormatting'
+	public static val DOC_PREPARE_RENAME = 'textDocument/prepareRename'
+	public static val DOC_RENAME = 'textDocument/rename'
+	public static val WORKSPACE_SYMBOL = 'workspace/symbol'
+	
+	public static val DID_OPEN_DOC = 'textDocument/didOpen'
+	public static val DID_CLOSE_DOC = 'textDocument/didClose'
+	public static val DID_CHANGE_DOC = 'textDocument/didChange'
+	public static val DID_SAVE_DOC = 'textDocument/didSave'
+	public static val DID_CHANGE_CONF = 'workspace/didChangeConfiguration'
+	public static val DID_CHANGE_FILES = 'workspace/didChangeWatchedFiles'
+	public static val SHOW_DIAGNOSTICS = 'textDocument/publishDiagnostics'
+	public static val SHOW_MESSAGE = 'window/showMessage'
+	public static val SHOW_MESSAGE_REQUEST = 'window/showMessageRequest'
+	public static val LOG_MESSAGE = 'window/logMessage'
+	public static val PROGRESS_NOTIFY = '$/progress'
+	public static val PROGRESS_CREATE = 'window/workDoneProgress/create'
+	public static val PROGRESS_CANCEL = 'window/workDoneProgress/cancel'
+	public static val TELEMETRY_EVENT = 'telemetry/event'
+	
+}
diff --git a/javatests/org/eclipse/lsp4j/services/MockLanguageClient.java b/javatests/org/eclipse/lsp4j/services/MockLanguageClient.java
new file mode 100644
index 0000000..f1b9071
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/services/MockLanguageClient.java
@@ -0,0 +1,59 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.test.services;
+
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+import org.eclipse.lsp4j.MessageActionItem;
+import org.eclipse.lsp4j.MessageParams;
+import org.eclipse.lsp4j.PublishDiagnosticsParams;
+import org.eclipse.lsp4j.ShowDocumentParams;
+import org.eclipse.lsp4j.ShowDocumentResult;
+import org.eclipse.lsp4j.ShowMessageRequestParams;
+import org.eclipse.lsp4j.WorkspaceFolder;
+import org.eclipse.lsp4j.services.LanguageClient;
+
+public class MockLanguageClient implements LanguageClient {
+
+	@Override
+	public void telemetryEvent(Object object) {
+	}
+
+	@Override
+	public void publishDiagnostics(PublishDiagnosticsParams diagnostics) {
+	}
+
+	@Override
+	public void showMessage(MessageParams messageParams) {
+	}
+
+	@Override
+	public CompletableFuture<MessageActionItem> showMessageRequest(ShowMessageRequestParams requestParams) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public CompletableFuture<ShowDocumentResult> showDocument(ShowDocumentParams requestParams) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public void logMessage(MessageParams message) {
+	}
+
+	@Override
+	public CompletableFuture<List<WorkspaceFolder>> workspaceFolders() {
+		throw new UnsupportedOperationException();
+	}
+	
+}
diff --git a/javatests/org/eclipse/lsp4j/services/MockLanguageServer.java b/javatests/org/eclipse/lsp4j/services/MockLanguageServer.java
new file mode 100644
index 0000000..7e09e37
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/services/MockLanguageServer.java
@@ -0,0 +1,82 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.test.services;
+
+import java.util.concurrent.CompletableFuture;
+
+import org.eclipse.lsp4j.DidChangeConfigurationParams;
+import org.eclipse.lsp4j.DidChangeTextDocumentParams;
+import org.eclipse.lsp4j.DidChangeWatchedFilesParams;
+import org.eclipse.lsp4j.DidCloseTextDocumentParams;
+import org.eclipse.lsp4j.DidOpenTextDocumentParams;
+import org.eclipse.lsp4j.DidSaveTextDocumentParams;
+import org.eclipse.lsp4j.InitializeParams;
+import org.eclipse.lsp4j.InitializeResult;
+import org.eclipse.lsp4j.WorkDoneProgressCancelParams;
+import org.eclipse.lsp4j.services.LanguageServer;
+import org.eclipse.lsp4j.services.TextDocumentService;
+import org.eclipse.lsp4j.services.WorkspaceService;
+
+public class MockLanguageServer implements LanguageServer, TextDocumentService, WorkspaceService {
+
+	@Override
+	public CompletableFuture<InitializeResult> initialize(InitializeParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public CompletableFuture<Object> shutdown() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public void exit() {
+	}
+
+	@Override
+	public TextDocumentService getTextDocumentService() {
+		return this;
+	}
+
+	@Override
+	public WorkspaceService getWorkspaceService() {
+		return this;
+	}
+
+	@Override
+	public void didChangeConfiguration(DidChangeConfigurationParams params) {
+	}
+
+	@Override
+	public void didChangeWatchedFiles(DidChangeWatchedFilesParams params) {
+	}
+
+	@Override
+	public void didOpen(DidOpenTextDocumentParams params) {
+	}
+
+	@Override
+	public void didChange(DidChangeTextDocumentParams params) {
+	}
+
+	@Override
+	public void didClose(DidCloseTextDocumentParams params) {
+	}
+
+	@Override
+	public void didSave(DidSaveTextDocumentParams params) {
+	}
+
+	@Override
+	public void cancelProgress(WorkDoneProgressCancelParams params) {
+	}
+}
diff --git a/javatests/org/eclipse/lsp4j/services/NullResponseTest.java b/javatests/org/eclipse/lsp4j/services/NullResponseTest.java
new file mode 100644
index 0000000..09ce173
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/services/NullResponseTest.java
@@ -0,0 +1,96 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.test.services;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+
+import org.eclipse.lsp4j.InitializeParams;
+import org.eclipse.lsp4j.InitializeResult;
+import org.eclipse.lsp4j.jsonrpc.Endpoint;
+import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
+import org.eclipse.lsp4j.jsonrpc.RemoteEndpoint;
+import org.eclipse.lsp4j.jsonrpc.json.JsonRpcMethod;
+import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
+import org.eclipse.lsp4j.jsonrpc.messages.Message;
+import org.eclipse.lsp4j.jsonrpc.messages.RequestMessage;
+import org.eclipse.lsp4j.jsonrpc.services.GenericEndpoint;
+import org.eclipse.lsp4j.jsonrpc.services.ServiceEndpoints;
+import org.eclipse.lsp4j.services.LanguageServer;
+import org.eclipse.lsp4j.services.TextDocumentService;
+import org.eclipse.lsp4j.services.WorkspaceService;
+import org.eclipse.lsp4j.test.LogMessageAccumulator;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class NullResponseTest implements LanguageServer {
+	
+	private Object shutdownReturn;
+
+	@Test
+	public void testNullResponse() throws InterruptedException, ExecutionException {
+		LogMessageAccumulator logMessages = new LogMessageAccumulator();
+		try {
+			logMessages.registerTo(GenericEndpoint.class);
+			
+			Endpoint endpoint = ServiceEndpoints.toEndpoint(this);
+			Map<String, JsonRpcMethod> methods = ServiceEndpoints.getSupportedMethods(LanguageServer.class);
+			MessageJsonHandler handler = new MessageJsonHandler(methods);
+			List<Message> msgs = new ArrayList<>();
+			MessageConsumer consumer = (message) -> {
+				msgs.add(message);
+			};
+			RemoteEndpoint re = new RemoteEndpoint(consumer, endpoint);
+			
+			RequestMessage request = new RequestMessage();
+			request.setId("1");
+			request.setMethod("shutdown");
+			re.consume(request);
+			Assert.assertEquals("{\"jsonrpc\":\"2.0\",\"id\":\"1\",\"result\":null}", handler.serialize(msgs.get(0)));
+			msgs.clear();
+			shutdownReturn = new Object();
+			re.consume(request);
+			Assert.assertEquals("{\"jsonrpc\":\"2.0\",\"id\":\"1\",\"result\":{}}", handler.serialize(msgs.get(0)));
+		} finally {
+			logMessages.unregister();
+		}
+	}
+
+	@Override
+	public CompletableFuture<InitializeResult> initialize(InitializeParams params) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public CompletableFuture<Object> shutdown() {
+		return CompletableFuture.completedFuture(shutdownReturn);
+	}
+
+	@Override
+	public void exit() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public TextDocumentService getTextDocumentService() {
+		return null;
+	}
+
+	@Override
+	public WorkspaceService getWorkspaceService() {
+		return null;
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/services/ProtocolTest.java b/javatests/org/eclipse/lsp4j/services/ProtocolTest.java
new file mode 100644
index 0000000..de69b86
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/services/ProtocolTest.java
@@ -0,0 +1,114 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.test.services;
+
+import java.io.IOException;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.lsp4j.DocumentLink;
+import org.eclipse.lsp4j.DocumentLinkParams;
+import org.eclipse.lsp4j.Position;
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.jsonrpc.CompletableFutures;
+import org.eclipse.lsp4j.jsonrpc.Launcher;
+import org.eclipse.lsp4j.services.LanguageServer;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ProtocolTest {
+	
+	private static final long TIMEOUT = 2000;
+
+	@Test public void testDocumentLink_01() throws Exception, ExecutionException {
+		LanguageServer languageServer = wrap(LanguageServer.class, new MockLanguageServer() {
+			@Override
+			public CompletableFuture<List<DocumentLink>> documentLink(DocumentLinkParams params) {
+				return CompletableFutures.computeAsync(canceler -> {
+					return new ArrayList<>();
+				});
+			}
+		});
+		
+		CompletableFuture<List<DocumentLink>> future = languageServer.getTextDocumentService().documentLink(new DocumentLinkParams(new TextDocumentIdentifier("test")));
+		List<DocumentLink> list = future.get(TIMEOUT, TimeUnit.MILLISECONDS);
+		
+		Assert.assertTrue(list.isEmpty());
+	}
+	
+	@Test public void testDocumentLink_02() throws Exception, ExecutionException {
+		LanguageServer languageServer = wrap(LanguageServer.class, new MockLanguageServer() {
+			@Override
+			public CompletableFuture<List<DocumentLink>> documentLink(DocumentLinkParams params) {
+				return CompletableFutures.computeAsync(canceler -> {
+					return null;
+				});
+			}
+		});
+		
+		CompletableFuture<List<DocumentLink>> future = languageServer.getTextDocumentService().documentLink(new DocumentLinkParams(new TextDocumentIdentifier("test")));
+		List<DocumentLink> list = future.get(TIMEOUT, TimeUnit.MILLISECONDS);
+		
+		Assert.assertNull(list);
+	}
+	
+	@Test public void testDocumentResolve() throws Exception, ExecutionException {
+		LanguageServer languageServer = wrap(LanguageServer.class, new MockLanguageServer() {
+			@Override
+			public CompletableFuture<DocumentLink> documentLinkResolve(DocumentLink params) {
+				return CompletableFutures.computeAsync(canceler -> {
+					params.setTarget("resolved");
+					return params;
+				});
+			}
+		});
+		
+		CompletableFuture<DocumentLink> future = languageServer.getTextDocumentService().documentLinkResolve(
+				new DocumentLink(new Range(new Position(0, 0), new Position(0, 0)), "unresolved")
+		);
+		DocumentLink resolved = future.get(TIMEOUT, TimeUnit.MILLISECONDS);
+		
+		Assert.assertEquals("resolved", resolved.getTarget());
+	}
+	
+	/**
+	 * creates a proxy, delegating to a remote endpoint, forwarding to another remote endpoint, that delegates to an actual implementation.
+	 * @param intf
+	 * @param impl
+	 * @return
+	 * @throws IOException 
+	 */
+	public <T> T wrap(Class<T> intf, T impl) {
+		PipedInputStream in1 = new PipedInputStream();
+		PipedOutputStream out1 = new PipedOutputStream();
+		Launcher<T> launcher1 = Launcher.createLauncher(impl, intf, in1, out1);
+		
+		PipedInputStream in2 = new PipedInputStream();
+		PipedOutputStream out2 = new PipedOutputStream();
+		Launcher<T> launcher2 = Launcher.createLauncher(new Object(), intf, in2, out2);
+		try {
+			in1.connect(out2);
+			in2.connect(out1);
+		} catch (IOException e) {
+			throw new IllegalStateException(e);
+		}
+		launcher1.startListening();
+		launcher2.startListening();
+		return launcher2.getRemoteProxy();
+	}
+}
diff --git a/javatests/org/eclipse/lsp4j/services/RpcMethodTest.java b/javatests/org/eclipse/lsp4j/services/RpcMethodTest.java
new file mode 100644
index 0000000..23e1d34
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/services/RpcMethodTest.java
@@ -0,0 +1,35 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.test.services;
+
+import java.util.Map;
+
+import org.eclipse.lsp4j.jsonrpc.json.JsonRpcMethod;
+import org.eclipse.lsp4j.jsonrpc.services.ServiceEndpoints;
+import org.eclipse.lsp4j.services.TextDocumentService;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class RpcMethodTest {
+
+	@Test public void testDocumentSymbol() {
+		Map<String, JsonRpcMethod> methods = ServiceEndpoints.getSupportedMethods(TextDocumentService.class);
+		JsonRpcMethod jsonRpcMethod = methods.get("textDocument/documentSymbol");
+		Assert.assertNotNull(jsonRpcMethod);
+	}
+	
+	@Test public void testCodelensResolve() {
+		Map<String, JsonRpcMethod> methods = ServiceEndpoints.getSupportedMethods(TextDocumentService.class);
+		Assert.assertNotNull(methods.get("codeLens/resolve"));
+		Assert.assertNotNull(methods.get("completionItem/resolve"));
+	}
+}
diff --git a/javatests/org/eclipse/lsp4j/services/ValidationTest.java b/javatests/org/eclipse/lsp4j/services/ValidationTest.java
new file mode 100644
index 0000000..5db16e4
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/services/ValidationTest.java
@@ -0,0 +1,68 @@
+/******************************************************************************
+ * Copyright (c) 2016 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.test.services;
+
+import org.eclipse.lsp4j.CodeLens;
+import org.eclipse.lsp4j.Position;
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.TextDocumentPositionParams;
+import org.eclipse.lsp4j.jsonrpc.MessageIssueException;
+import org.eclipse.lsp4j.jsonrpc.messages.Message;
+import org.eclipse.lsp4j.jsonrpc.messages.RequestMessage;
+import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage;
+import org.eclipse.lsp4j.jsonrpc.validation.ReflectiveMessageValidator;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ValidationTest {
+	
+	ReflectiveMessageValidator validator = new ReflectiveMessageValidator();
+
+	@Test
+	public void testInvalidCompletion() {
+		RequestMessage message = new RequestMessage();
+		message.setJsonrpc("2.0");
+		message.setId("1");
+		message.setMethod(MessageMethods.DOC_COMPLETION);
+		
+		TextDocumentPositionParams params = new TextDocumentPositionParams();
+		params.setTextDocument(new TextDocumentIdentifier("file:///tmp/foo"));
+		message.setParams(params);
+		
+		assertIssues(message, "The accessor 'TextDocumentPositionParams.getPosition()' must return a non-null value.");
+	}
+	
+	@Test
+	public void testInvalidCodeLens() {
+		ResponseMessage message = new ResponseMessage();
+		message.setId("1");
+		CodeLens codeLens = new CodeLens(new Range(new Position(3, 32), new Position(3, 35)), null, null);
+		// forbidden self reference!
+		codeLens.setData(codeLens);
+		message.setResult(codeLens);
+		assertIssues(message, "An element of the message has a direct or indirect reference to itself.");
+	}
+	
+	private void assertIssues(Message message, CharSequence expectedIssues) {
+		try {
+			validator.consume(message);
+			Assert.fail("Expected InvalidMessageException: " + expectedIssues + ".");
+		} catch (MessageIssueException e) {
+			String expected = expectedIssues.toString();
+			String actual = LineEndings.toSystemLineEndings(e.getMessage());
+			// The expectation may be a prefix of the actual exception message
+			if (!actual.startsWith(expected))
+				Assert.assertEquals(expected, actual);
+		}
+	}
+}
diff --git a/javatests/org/eclipse/lsp4j/util/DocumentSymbolsTest.java b/javatests/org/eclipse/lsp4j/util/DocumentSymbolsTest.java
new file mode 100644
index 0000000..33addfc
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/util/DocumentSymbolsTest.java
@@ -0,0 +1,74 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.test.util;
+
+import static java.util.stream.Collectors.toList;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+import org.eclipse.lsp4j.DocumentSymbol;
+import org.eclipse.lsp4j.util.DocumentSymbols;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class DocumentSymbolsTest {
+
+	@Test(expected = NullPointerException.class)
+	public void asIterator_null() {
+		DocumentSymbols.asIterator(null);
+	}
+
+	@Test
+	public void asIterator() {
+		DocumentSymbol depth0 = new DocumentSymbol();
+		depth0.setName("root");
+
+		DocumentSymbol depth1_0 = new DocumentSymbol();
+		depth1_0.setName("A1");
+		DocumentSymbol depth1_1 = new DocumentSymbol();
+		depth1_1.setName("B1");
+		DocumentSymbol depth1_2 = new DocumentSymbol();
+		depth1_2.setName("C1");
+		depth0.setChildren(Arrays.asList(depth1_0, depth1_1, depth1_2));
+
+		DocumentSymbol depth2_0_0 = new DocumentSymbol();
+		depth2_0_0.setName("A11");
+		DocumentSymbol depth2_0_1 = new DocumentSymbol();
+		depth2_0_1.setName("A12");
+		depth1_0.setChildren(Arrays.asList(depth2_0_0, depth2_0_1));
+
+		DocumentSymbol depth2_1_0 = new DocumentSymbol();
+		depth2_1_0.setName("B11");
+		DocumentSymbol depth2_1_1 = new DocumentSymbol();
+		depth2_1_1.setName("B12");
+		depth1_1.setChildren(Arrays.asList(depth2_1_0, depth2_1_1));
+
+		DocumentSymbol depth2_2_0 = new DocumentSymbol();
+		depth2_2_0.setName("C11");
+		DocumentSymbol depth2_2_1 = new DocumentSymbol();
+		depth2_2_1.setName("C12");
+		depth1_2.setChildren(Arrays.asList(depth2_2_0, depth2_2_1));
+
+		Iterator<DocumentSymbol> iterator = DocumentSymbols.asIterator(depth0);
+		Iterable<DocumentSymbol> iterable = () -> iterator;
+		Stream<DocumentSymbol> stream = StreamSupport.stream(iterable.spliterator(), false);
+		List<String> actual = stream.map(symbol -> symbol.getName()).collect(toList());
+		List<String> expected = Arrays.asList("root, A1", "B1", "C1", "A11", "A12", "B11", "B12", "C11", "C12");
+
+		Assert.assertEquals(Arrays.toString(expected.toArray()), Arrays.toString(actual.toArray()));
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/util/PositionsTest.java b/javatests/org/eclipse/lsp4j/util/PositionsTest.java
new file mode 100644
index 0000000..ea047d1
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/util/PositionsTest.java
@@ -0,0 +1,62 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.test.util;
+
+import org.eclipse.lsp4j.Position;
+import org.eclipse.lsp4j.util.Positions;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class PositionsTest {
+
+	@Test(expected = NullPointerException.class)
+	public void isBefore_nullLeft() {
+		Positions.isBefore(null, new Position(0, 0));
+	}
+
+	@Test(expected = NullPointerException.class)
+	public void isBefore_nullRight() {
+		Positions.isBefore(new Position(0, 0), null);
+	}
+
+	@Test
+	public void isBefore_equals() {
+		Position position = new Position(3, 3);
+		Assert.assertFalse(Positions.isBefore(position, position));
+	}
+
+	@Test
+	public void isBefore_same() {
+		Assert.assertFalse(Positions.isBefore(new Position(3, 3), new Position(3, 3)));
+	}
+
+	@Test
+	public void isBefore_beforeSameLine() {
+		Assert.assertTrue(Positions.isBefore(new Position(3, 3), new Position(3, 4)));
+	}
+
+	@Test
+	public void isBefore_before() {
+		Assert.assertTrue(Positions.isBefore(new Position(3, 3), new Position(4, 3)));
+	}
+
+	@Test
+	public void isBefore_afterSameLine() {
+		Assert.assertFalse(Positions.isBefore(new Position(3, 3), new Position(3, 2)));
+	}
+
+	@Test
+	public void isBefore_after() {
+		Assert.assertFalse(Positions.isBefore(new Position(3, 3), new Position(2, 3)));
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/util/RangesTest.java b/javatests/org/eclipse/lsp4j/util/RangesTest.java
new file mode 100644
index 0000000..62ecaae
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/util/RangesTest.java
@@ -0,0 +1,132 @@
+/******************************************************************************
+ * Copyright (c) 2018 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.test.util;
+
+import org.eclipse.lsp4j.Position;
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.util.Ranges;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class RangesTest {
+
+	@Test(expected = NullPointerException.class)
+	public void containsRange_nullBigger() {
+		Ranges.containsRange(null, newRange(0, 0, 1, 1));
+	}
+
+	@Test(expected = NullPointerException.class)
+	public void containsRange_nullSmaller() {
+		Ranges.containsRange(newRange(0, 0, 1, 1), null);
+	}
+
+	@Test
+	public void containsRange_beforeAbove() {
+		Assert.assertFalse(Ranges.containsRange(newRange(2, 2, 3, 3), newRange(0, 0, 1, 1)));
+	}
+
+	@Test
+	public void containsRange_beforeSameLine() {
+		Assert.assertFalse(Ranges.containsRange(newRange(1, 2, 3, 3), newRange(0, 0, 1, 1)));
+	}
+
+	@Test
+	public void containsRange_beforeIntersects() {
+		Assert.assertFalse(Ranges.containsRange(newRange(1, 2, 3, 3), newRange(0, 0, 1, 3)));
+	}
+
+	@Test
+	public void containsRange_same() {
+		Assert.assertTrue(Ranges.containsRange(newRange(0, 0, 1, 3), newRange(0, 0, 1, 3)));
+	}
+
+	@Test
+	public void containsRange_equals() {
+		Range range = newRange(0, 0, 1, 3);
+		Assert.assertTrue(Ranges.containsRange(range, range));
+	}
+
+	@Test
+	public void containsRange_inside() {
+		Assert.assertTrue(Ranges.containsRange(newRange(0, 0, 3, 3), newRange(1, 1, 2, 2)));
+	}
+
+	@Test
+	public void containsRange_afterBelow() {
+		Assert.assertFalse(Ranges.containsRange(newRange(2, 2, 3, 3), newRange(4, 4, 5, 5)));
+	}
+
+	@Test
+	public void containsRange_afterSameLine() {
+		Assert.assertFalse(Ranges.containsRange(newRange(2, 2, 3, 3), newRange(3, 4, 5, 5)));
+	}
+
+	@Test
+	public void containsRange_afterIntersects() {
+		Assert.assertFalse(Ranges.containsRange(newRange(2, 2, 3, 3), newRange(3, 1, 5, 5)));
+	}
+
+	@Test
+	public void containsRange_overlaps() {
+		Assert.assertFalse(Ranges.containsRange(newRange(2, 2, 3, 3), newRange(1, 1, 5, 5)));
+	}
+
+	@Test(expected = NullPointerException.class)
+	public void containsPosition_nullRange() {
+		Ranges.containsPosition(null, new Position(0, 0));
+	}
+
+	@Test(expected = NullPointerException.class)
+	public void containsPosition_nullPosition() {
+		Ranges.containsPosition(newRange(0, 0, 1, 1), null);
+	}
+
+	@Test
+	public void containsPosition_beforeAbove() {
+		Assert.assertFalse(Ranges.containsPosition(newRange(1, 1, 2, 2), new Position(0, 1)));
+	}
+
+	@Test
+	public void containsPosition_beforeSameLine() {
+		Assert.assertFalse(Ranges.containsPosition(newRange(1, 3, 2, 2), new Position(1, 2)));
+	}
+
+	@Test
+	public void containsPosition_leftBorder() {
+		Assert.assertTrue(Ranges.containsPosition(newRange(1, 3, 2, 2), new Position(1, 3)));
+	}
+
+	@Test
+	public void containsPosition_inside() {
+		Assert.assertTrue(Ranges.containsPosition(newRange(1, 3, 2, 2), new Position(1, 4)));
+	}
+
+	@Test
+	public void containsPosition_rightBorder() {
+		Assert.assertTrue(Ranges.containsPosition(newRange(1, 3, 2, 2), new Position(2, 2)));
+	}
+
+	@Test
+	public void containsPosition_afterSameLine() {
+		Assert.assertFalse(Ranges.containsPosition(newRange(1, 1, 2, 2), new Position(2, 4)));
+	}
+
+	@Test
+	public void containsPosition_afterBelow() {
+		Assert.assertFalse(Ranges.containsPosition(newRange(1, 3, 2, 2), new Position(3, 3)));
+	}
+
+	private static Range newRange(int startLine, int startCharacter, int endLine, int endCharacter) {
+		return new Range(new Position(startLine, startCharacter), new Position(endLine, endCharacter));
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/websocket/jakarta/test/MockConnectionTest.java b/javatests/org/eclipse/lsp4j/websocket/jakarta/test/MockConnectionTest.java
new file mode 100644
index 0000000..c44dd44
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/websocket/jakarta/test/MockConnectionTest.java
@@ -0,0 +1,170 @@
+/******************************************************************************
+ * Copyright (c) 2019, 2021 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.websocket.jakarta.test;
+
+import java.util.Collection;
+import java.util.Random;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Supplier;
+
+import org.eclipse.lsp4j.jsonrpc.Launcher;
+import org.eclipse.lsp4j.jsonrpc.services.JsonNotification;
+import org.eclipse.lsp4j.jsonrpc.services.JsonRequest;
+import org.eclipse.lsp4j.websocket.jakarta.WebSocketEndpoint;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class MockConnectionTest {
+	
+	private static final long TIMEOUT = 2000;
+	
+	private Client client;
+	private Server server;
+	
+	@SuppressWarnings("resource")
+	@Before
+	public void setup() {
+		client = new Client();
+		server = new Server();
+		MockSession clientSession = new MockSession();
+		MockSession serverSession = new MockSession();
+		clientSession.connect(serverSession);
+		clientSession.open(new ClientSideEndpoint());
+		serverSession.open(new ServerSideEndpoint());
+	}
+	
+	@Test
+	public void testClientRequest() throws Exception {
+		CompletableFuture<String> future = client.server.request("foo");
+		String result = future.get(TIMEOUT, TimeUnit.MILLISECONDS);
+		Assert.assertEquals("foobar", result);
+	}
+	
+	@Test
+	public void testNotifications() throws Exception {
+		server.client.notify("12");
+		await(() -> client.result.length() == 2);
+		client.server.notify("foo");
+		await(() -> server.result.length() == 3);
+		server.client.notify("34");
+		await(() -> client.result.length() == 4);
+		client.server.notify("bar");
+		await(() -> server.result.length() == 6);
+		server.client.notify("56");
+		await(() -> client.result.length() == 6);
+		
+		Assert.assertEquals("foobar", server.result);
+		Assert.assertEquals("123456", client.result);
+	}
+	
+	@Test
+	public void testChunkedNotification() throws Exception {
+		StringBuilder messageBuilder = new StringBuilder();
+		Random random = new Random(1);
+		for (int i = 0; i < 3 * MockSession.MAX_CHUNK_SIZE; i++) {
+			messageBuilder.append((char) ('a' + random.nextInt('z' - 'a' + 1)));
+		}
+		String message = messageBuilder.toString();
+		
+		server.client.notify(message);
+		await(() -> client.result.length() == message.length());
+		
+		Assert.assertEquals(message, client.result);
+	}
+
+	private void await(Supplier<Boolean> condition) throws InterruptedException {
+		long startTime = System.currentTimeMillis();
+		while (!condition.get()) {
+			Thread.sleep(20);
+			if (System.currentTimeMillis() - startTime > TIMEOUT) {
+				Assert.fail("Timeout elapsed while waiting for condition.\n");
+			}
+		}
+	}
+	
+	private static interface ClientInterface {
+		
+		@JsonNotification("client/notify")
+		void notify(String arg);
+		
+	}
+	
+	private static class Client implements ClientInterface {
+		ServerInterface server;
+		String result = "";
+
+		@Override
+		public void notify(String arg) {
+			this.result += arg;
+		}
+	}
+	
+	private static interface ServerInterface {
+		
+		@JsonRequest("server/request")
+		CompletableFuture<String> request(String arg);
+		
+		@JsonNotification("server/notify")
+		void notify(String arg);
+		
+	}
+	
+	private static class Server implements ServerInterface {
+		ClientInterface client;
+		String result = "";
+		
+		@Override
+		public CompletableFuture<String> request(String arg) {
+			return CompletableFuture.supplyAsync(() -> arg + "bar");
+		}
+		
+		@Override
+		public void notify(String arg) {
+			this.result += arg;
+		}
+	}
+	
+	private class ClientSideEndpoint extends WebSocketEndpoint<ServerInterface> {
+
+		@Override
+		protected void configure(Launcher.Builder<ServerInterface> builder) {
+			builder
+				.setLocalService(client)
+				.setRemoteInterface(ServerInterface.class);
+		}
+		
+		@Override
+		protected void connect(Collection<Object> localServices, ServerInterface remoteProxy) {
+			localServices.forEach(s -> ((Client) s).server = remoteProxy);
+		}
+		
+	}
+	
+	private class ServerSideEndpoint extends WebSocketEndpoint<ClientInterface> {
+		
+		@Override
+		protected void configure(Launcher.Builder<ClientInterface> builder) {
+			builder
+				.setLocalService(server)
+				.setRemoteInterface(ClientInterface.class);
+		}
+		
+		@Override
+		protected void connect(Collection<Object> localServices, ClientInterface remoteProxy) {
+			localServices.forEach(s -> ((Server) s).client = remoteProxy);
+		}
+		
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/websocket/jakarta/test/MockEndpointConfig.java b/javatests/org/eclipse/lsp4j/websocket/jakarta/test/MockEndpointConfig.java
new file mode 100644
index 0000000..7304a69
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/websocket/jakarta/test/MockEndpointConfig.java
@@ -0,0 +1,39 @@
+/******************************************************************************
+ * Copyright (c) 2019, 2021 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.websocket.jakarta.test;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import jakarta.websocket.Decoder;
+import jakarta.websocket.Encoder;
+import jakarta.websocket.EndpointConfig;
+
+public class MockEndpointConfig implements EndpointConfig {
+
+	@Override
+	public List<Class<? extends Encoder>> getEncoders() {
+		return Collections.emptyList();
+	}
+
+	@Override
+	public List<Class<? extends Decoder>> getDecoders() {
+		return Collections.emptyList();
+	}
+
+	@Override
+	public Map<String, Object> getUserProperties() {
+		return Collections.emptyMap();
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/websocket/jakarta/test/MockSession.java b/javatests/org/eclipse/lsp4j/websocket/jakarta/test/MockSession.java
new file mode 100644
index 0000000..55e4770
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/websocket/jakarta/test/MockSession.java
@@ -0,0 +1,346 @@
+/******************************************************************************
+ * Copyright (c) 2019, 2021 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.websocket.jakarta.test;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.ByteBuffer;
+import java.security.Principal;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Future;
+
+import jakarta.websocket.CloseReason;
+import jakarta.websocket.EncodeException;
+import jakarta.websocket.Endpoint;
+import jakarta.websocket.Extension;
+import jakarta.websocket.MessageHandler;
+import jakarta.websocket.MessageHandler.Partial;
+import jakarta.websocket.MessageHandler.Whole;
+import jakarta.websocket.RemoteEndpoint;
+import jakarta.websocket.SendHandler;
+import jakarta.websocket.SendResult;
+import jakarta.websocket.Session;
+import jakarta.websocket.WebSocketContainer;
+
+public class MockSession implements Session {
+	
+	public static final int MAX_CHUNK_SIZE = 100;
+	
+	private final BasicRemote basicRemote = new BasicRemote();
+	private final AsyncRemote asyncRemote = new AsyncRemote();
+	private final Set<MessageHandler> messageHandlers = new HashSet<>();
+	private Endpoint endpoint;
+	private MockSession connectedSession;
+	private boolean isClosed;
+	private StringBuilder partialMessage;
+	
+	public void connect(MockSession other) {
+		this.connectedSession = other;
+		other.connectedSession = this;
+	}
+
+	@Override
+	public RemoteEndpoint.Async getAsyncRemote() {
+		return asyncRemote;
+	}
+
+	@Override
+	public RemoteEndpoint.Basic getBasicRemote() {
+		return basicRemote;
+	}
+	
+	public void open(Endpoint endpoint) {
+		this.endpoint = endpoint;
+		endpoint.onOpen(this, new MockEndpointConfig());
+	}
+
+	@Override
+	public void close() throws IOException {
+		close(new CloseReason(CloseReason.CloseCodes.NORMAL_CLOSURE, "OK"));
+	}
+
+	@Override
+	public void close(CloseReason closeReason) throws IOException {
+		isClosed = true;
+		endpoint.onClose(this, closeReason);
+	}
+
+	@Override
+	public void addMessageHandler(MessageHandler handler) throws IllegalStateException {
+		if (!messageHandlers.add(handler))
+			throw new IllegalStateException();
+	}
+	
+
+	@Override
+	public <T> void addMessageHandler(Class<T> clazz, Whole<T> handler) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public <T> void addMessageHandler(Class<T> clazz, Partial<T> handler) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public Set<MessageHandler> getMessageHandlers() {
+		return messageHandlers;
+	}
+
+	@Override
+	public void removeMessageHandler(MessageHandler handler) {
+		messageHandlers.remove(handler);
+	}
+	
+	@SuppressWarnings("unchecked")
+	protected void dispatch(String message, boolean lastChunk) {
+		if (lastChunk) {
+			String wholeMessage = message;
+			if (partialMessage != null) {
+				partialMessage.append(message);
+				wholeMessage = partialMessage.toString();
+				partialMessage = null;
+			}
+			for (MessageHandler h : connectedSession.messageHandlers) {
+				if (h instanceof MessageHandler.Whole<?>)
+					((MessageHandler.Whole<String>) h).onMessage(wholeMessage);
+				else
+					((MessageHandler.Partial<String>) h).onMessage(message, true);
+			};
+		} else {
+			if (partialMessage == null) {
+				partialMessage = new StringBuilder();
+			}
+			for (MessageHandler h : connectedSession.messageHandlers) {
+				if (h instanceof MessageHandler.Partial<?>)
+					((MessageHandler.Partial<String>) h).onMessage(message, false);
+			};
+			partialMessage.append(message);
+		}
+	}
+
+	@Override
+	public WebSocketContainer getContainer() {
+		return null;
+	}
+
+	@Override
+	public String getProtocolVersion() {
+		return "13";
+	}
+
+	@Override
+	public String getNegotiatedSubprotocol() {
+		return null;
+	}
+
+	@Override
+	public List<Extension> getNegotiatedExtensions() {
+		return Collections.emptyList();
+	}
+
+	@Override
+	public boolean isSecure() {
+		return true;
+	}
+
+	@Override
+	public boolean isOpen() {
+		return !isClosed;
+	}
+
+	@Override
+	public long getMaxIdleTimeout() {
+		return 10000;
+	}
+
+	@Override
+	public void setMaxIdleTimeout(long milliseconds) {
+	}
+
+	@Override
+	public void setMaxBinaryMessageBufferSize(int length) {
+	}
+
+	@Override
+	public int getMaxBinaryMessageBufferSize() {
+		return 100;
+	}
+
+	@Override
+	public void setMaxTextMessageBufferSize(int length) {
+	}
+
+	@Override
+	public int getMaxTextMessageBufferSize() {
+		return MAX_CHUNK_SIZE;
+	}
+
+	@Override
+	public String getId() {
+		return "mock";
+	}
+
+	@Override
+	public URI getRequestURI() {
+		try {
+			return new URI("http://localhost:8080/mock");
+		} catch (URISyntaxException e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	@Override
+	public Map<String, List<String>> getRequestParameterMap() {
+		return Collections.emptyMap();
+	}
+
+	@Override
+	public String getQueryString() {
+		return "";
+	}
+
+	@Override
+	public Map<String, String> getPathParameters() {
+		return Collections.emptyMap();
+	}
+
+	@Override
+	public Map<String, Object> getUserProperties() {
+		return Collections.emptyMap();
+	}
+
+	@Override
+	public Principal getUserPrincipal() {
+		return null;
+	}
+
+	@Override
+	public Set<Session> getOpenSessions() {
+		return Collections.singleton(this);
+	}
+	
+	private class BasicRemote extends AbstractRemoteEndpoint implements RemoteEndpoint.Basic {
+
+		@Override
+		public void sendText(String text) throws IOException {
+			dispatch(text, true);
+		}
+
+		@Override
+		public void sendBinary(ByteBuffer data) throws IOException {
+		}
+
+		@Override
+		public void sendText(String partialMessage, boolean isLast) throws IOException {
+			dispatch(partialMessage, isLast);
+		}
+
+		@Override
+		public void sendBinary(ByteBuffer partialByte, boolean isLast) throws IOException {
+		}
+
+		@Override
+		public OutputStream getSendStream() throws IOException {
+			return null;
+		}
+
+		@Override
+		public Writer getSendWriter() throws IOException {
+			return null;
+		}
+
+		@Override
+		public void sendObject(Object data) throws IOException, EncodeException {
+		}
+		
+	}
+	
+	private class AsyncRemote extends AbstractRemoteEndpoint implements RemoteEndpoint.Async {
+
+		@Override
+		public long getSendTimeout() {
+			return 1000;
+		}
+
+		@Override
+		public void setSendTimeout(long timeoutmillis) {
+		}
+
+		@Override
+		public void sendText(String text, SendHandler handler) {
+			sendText(text).thenRun(() -> {
+				handler.onResult(new SendResult());
+			});
+		}
+
+		@Override
+		public CompletableFuture<Void> sendText(String text) {
+			return CompletableFuture.runAsync(() -> {
+				dispatch(text, true);
+			});
+		}
+
+		@Override
+		public Future<Void> sendBinary(ByteBuffer data) {
+			return null;
+		}
+
+		@Override
+		public void sendBinary(ByteBuffer data, SendHandler handler) {
+		}
+
+		@Override
+		public Future<Void> sendObject(Object data) {
+			return null;
+		}
+
+		@Override
+		public void sendObject(Object data, SendHandler handler) {
+		}
+		
+	}
+	
+	private static abstract class AbstractRemoteEndpoint implements RemoteEndpoint {
+
+		@Override
+		public void setBatchingAllowed(boolean allowed) throws IOException {
+		}
+
+		@Override
+		public boolean getBatchingAllowed() {
+			return false;
+		}
+
+		@Override
+		public void flushBatch() throws IOException {
+		}
+
+		@Override
+		public void sendPing(ByteBuffer applicationData) throws IOException, IllegalArgumentException {
+		}
+
+		@Override
+		public void sendPong(ByteBuffer applicationData) throws IOException, IllegalArgumentException {
+		}
+		
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/websocket/test/MockConnectionTest.java b/javatests/org/eclipse/lsp4j/websocket/test/MockConnectionTest.java
new file mode 100644
index 0000000..37ecfd6
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/websocket/test/MockConnectionTest.java
@@ -0,0 +1,170 @@
+/******************************************************************************
+ * Copyright (c) 2019 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.websocket.test;
+
+import java.util.Collection;
+import java.util.Random;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Supplier;
+
+import org.eclipse.lsp4j.jsonrpc.Launcher;
+import org.eclipse.lsp4j.jsonrpc.services.JsonNotification;
+import org.eclipse.lsp4j.jsonrpc.services.JsonRequest;
+import org.eclipse.lsp4j.websocket.WebSocketEndpoint;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class MockConnectionTest {
+	
+	private static final long TIMEOUT = 2000;
+	
+	private Client client;
+	private Server server;
+	
+	@SuppressWarnings("resource")
+	@Before
+	public void setup() {
+		client = new Client();
+		server = new Server();
+		MockSession clientSession = new MockSession();
+		MockSession serverSession = new MockSession();
+		clientSession.connect(serverSession);
+		clientSession.open(new ClientSideEndpoint());
+		serverSession.open(new ServerSideEndpoint());
+	}
+	
+	@Test
+	public void testClientRequest() throws Exception {
+		CompletableFuture<String> future = client.server.request("foo");
+		String result = future.get(TIMEOUT, TimeUnit.MILLISECONDS);
+		Assert.assertEquals("foobar", result);
+	}
+	
+	@Test
+	public void testNotifications() throws Exception {
+		server.client.notify("12");
+		await(() -> client.result.length() == 2);
+		client.server.notify("foo");
+		await(() -> server.result.length() == 3);
+		server.client.notify("34");
+		await(() -> client.result.length() == 4);
+		client.server.notify("bar");
+		await(() -> server.result.length() == 6);
+		server.client.notify("56");
+		await(() -> client.result.length() == 6);
+		
+		Assert.assertEquals("foobar", server.result);
+		Assert.assertEquals("123456", client.result);
+	}
+	
+	@Test
+	public void testChunkedNotification() throws Exception {
+		StringBuilder messageBuilder = new StringBuilder();
+		Random random = new Random(1);
+		for (int i = 0; i < 3 * MockSession.MAX_CHUNK_SIZE; i++) {
+			messageBuilder.append((char) ('a' + random.nextInt('z' - 'a' + 1)));
+		}
+		String message = messageBuilder.toString();
+		
+		server.client.notify(message);
+		await(() -> client.result.length() == message.length());
+		
+		Assert.assertEquals(message, client.result);
+	}
+
+	private void await(Supplier<Boolean> condition) throws InterruptedException {
+		long startTime = System.currentTimeMillis();
+		while (!condition.get()) {
+			Thread.sleep(20);
+			if (System.currentTimeMillis() - startTime > TIMEOUT) {
+				Assert.fail("Timeout elapsed while waiting for condition.\n");
+			}
+		}
+	}
+	
+	private static interface ClientInterface {
+		
+		@JsonNotification("client/notify")
+		void notify(String arg);
+		
+	}
+	
+	private static class Client implements ClientInterface {
+		ServerInterface server;
+		String result = "";
+
+		@Override
+		public void notify(String arg) {
+			this.result += arg;
+		}
+	}
+	
+	private static interface ServerInterface {
+		
+		@JsonRequest("server/request")
+		CompletableFuture<String> request(String arg);
+		
+		@JsonNotification("server/notify")
+		void notify(String arg);
+		
+	}
+	
+	private static class Server implements ServerInterface {
+		ClientInterface client;
+		String result = "";
+		
+		@Override
+		public CompletableFuture<String> request(String arg) {
+			return CompletableFuture.supplyAsync(() -> arg + "bar");
+		}
+		
+		@Override
+		public void notify(String arg) {
+			this.result += arg;
+		}
+	}
+	
+	private class ClientSideEndpoint extends WebSocketEndpoint<ServerInterface> {
+
+		@Override
+		protected void configure(Launcher.Builder<ServerInterface> builder) {
+			builder
+				.setLocalService(client)
+				.setRemoteInterface(ServerInterface.class);
+		}
+		
+		@Override
+		protected void connect(Collection<Object> localServices, ServerInterface remoteProxy) {
+			localServices.forEach(s -> ((Client) s).server = remoteProxy);
+		}
+		
+	}
+	
+	private class ServerSideEndpoint extends WebSocketEndpoint<ClientInterface> {
+		
+		@Override
+		protected void configure(Launcher.Builder<ClientInterface> builder) {
+			builder
+				.setLocalService(server)
+				.setRemoteInterface(ClientInterface.class);
+		}
+		
+		@Override
+		protected void connect(Collection<Object> localServices, ClientInterface remoteProxy) {
+			localServices.forEach(s -> ((Server) s).client = remoteProxy);
+		}
+		
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/websocket/test/MockEndpointConfig.java b/javatests/org/eclipse/lsp4j/websocket/test/MockEndpointConfig.java
new file mode 100644
index 0000000..72101cf
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/websocket/test/MockEndpointConfig.java
@@ -0,0 +1,39 @@
+/******************************************************************************
+ * Copyright (c) 2019 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.websocket.test;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import javax.websocket.Decoder;
+import javax.websocket.Encoder;
+import javax.websocket.EndpointConfig;
+
+public class MockEndpointConfig implements EndpointConfig {
+
+	@Override
+	public List<Class<? extends Encoder>> getEncoders() {
+		return Collections.emptyList();
+	}
+
+	@Override
+	public List<Class<? extends Decoder>> getDecoders() {
+		return Collections.emptyList();
+	}
+
+	@Override
+	public Map<String, Object> getUserProperties() {
+		return Collections.emptyMap();
+	}
+
+}
diff --git a/javatests/org/eclipse/lsp4j/websocket/test/MockSession.java b/javatests/org/eclipse/lsp4j/websocket/test/MockSession.java
new file mode 100644
index 0000000..6d7039c
--- /dev/null
+++ b/javatests/org/eclipse/lsp4j/websocket/test/MockSession.java
@@ -0,0 +1,333 @@
+/******************************************************************************
+ * Copyright (c) 2019 TypeFox and others.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * 
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ ******************************************************************************/
+package org.eclipse.lsp4j.websocket.test;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.ByteBuffer;
+import java.security.Principal;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Future;
+
+import javax.websocket.CloseReason;
+import javax.websocket.EncodeException;
+import javax.websocket.Endpoint;
+import javax.websocket.Extension;
+import javax.websocket.MessageHandler;
+import javax.websocket.RemoteEndpoint;
+import javax.websocket.SendHandler;
+import javax.websocket.SendResult;
+import javax.websocket.Session;
+import javax.websocket.WebSocketContainer;
+
+public class MockSession implements Session {
+	
+	public static final int MAX_CHUNK_SIZE = 100;
+	
+	private final BasicRemote basicRemote = new BasicRemote();
+	private final AsyncRemote asyncRemote = new AsyncRemote();
+	private final Set<MessageHandler> messageHandlers = new HashSet<>();
+	private Endpoint endpoint;
+	private MockSession connectedSession;
+	private boolean isClosed;
+	private StringBuilder partialMessage;
+	
+	public void connect(MockSession other) {
+		this.connectedSession = other;
+		other.connectedSession = this;
+	}
+
+	@Override
+	public RemoteEndpoint.Async getAsyncRemote() {
+		return asyncRemote;
+	}
+
+	@Override
+	public RemoteEndpoint.Basic getBasicRemote() {
+		return basicRemote;
+	}
+	
+	public void open(Endpoint endpoint) {
+		this.endpoint = endpoint;
+		endpoint.onOpen(this, new MockEndpointConfig());
+	}
+
+	@Override
+	public void close() throws IOException {
+		close(new CloseReason(CloseReason.CloseCodes.NORMAL_CLOSURE, "OK"));
+	}
+
+	@Override
+	public void close(CloseReason closeReason) throws IOException {
+		isClosed = true;
+		endpoint.onClose(this, closeReason);
+	}
+
+	@Override
+	public void addMessageHandler(MessageHandler handler) throws IllegalStateException {
+		if (!messageHandlers.add(handler))
+			throw new IllegalStateException();
+	}
+
+	@Override
+	public Set<MessageHandler> getMessageHandlers() {
+		return messageHandlers;
+	}
+
+	@Override
+	public void removeMessageHandler(MessageHandler handler) {
+		messageHandlers.remove(handler);
+	}
+	
+	@SuppressWarnings("unchecked")
+	protected void dispatch(String message, boolean lastChunk) {
+		if (lastChunk) {
+			String wholeMessage = message;
+			if (partialMessage != null) {
+				partialMessage.append(message);
+				wholeMessage = partialMessage.toString();
+				partialMessage = null;
+			}
+			for (MessageHandler h : connectedSession.messageHandlers) {
+				if (h instanceof MessageHandler.Whole<?>)
+					((MessageHandler.Whole<String>) h).onMessage(wholeMessage);
+				else
+					((MessageHandler.Partial<String>) h).onMessage(message, true);
+			};
+		} else {
+			if (partialMessage == null) {
+				partialMessage = new StringBuilder();
+			}
+			for (MessageHandler h : connectedSession.messageHandlers) {
+				if (h instanceof MessageHandler.Partial<?>)
+					((MessageHandler.Partial<String>) h).onMessage(message, false);
+			};
+			partialMessage.append(message);
+		}
+	}
+
+	@Override
+	public WebSocketContainer getContainer() {
+		return null;
+	}
+
+	@Override
+	public String getProtocolVersion() {
+		return "13";
+	}
+
+	@Override
+	public String getNegotiatedSubprotocol() {
+		return null;
+	}
+
+	@Override
+	public List<Extension> getNegotiatedExtensions() {
+		return Collections.emptyList();
+	}
+
+	@Override
+	public boolean isSecure() {
+		return true;
+	}
+
+	@Override
+	public boolean isOpen() {
+		return !isClosed;
+	}
+
+	@Override
+	public long getMaxIdleTimeout() {
+		return 10000;
+	}
+
+	@Override
+	public void setMaxIdleTimeout(long milliseconds) {
+	}
+
+	@Override
+	public void setMaxBinaryMessageBufferSize(int length) {
+	}
+
+	@Override
+	public int getMaxBinaryMessageBufferSize() {
+		return 100;
+	}
+
+	@Override
+	public void setMaxTextMessageBufferSize(int length) {
+	}
+
+	@Override
+	public int getMaxTextMessageBufferSize() {
+		return MAX_CHUNK_SIZE;
+	}
+
+	@Override
+	public String getId() {
+		return "mock";
+	}
+
+	@Override
+	public URI getRequestURI() {
+		try {
+			return new URI("http://localhost:8080/mock");
+		} catch (URISyntaxException e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	@Override
+	public Map<String, List<String>> getRequestParameterMap() {
+		return Collections.emptyMap();
+	}
+
+	@Override
+	public String getQueryString() {
+		return "";
+	}
+
+	@Override
+	public Map<String, String> getPathParameters() {
+		return Collections.emptyMap();
+	}
+
+	@Override
+	public Map<String, Object> getUserProperties() {
+		return Collections.emptyMap();
+	}
+
+	@Override
+	public Principal getUserPrincipal() {
+		return null;
+	}
+
+	@Override
+	public Set<Session> getOpenSessions() {
+		return Collections.singleton(this);
+	}
+	
+	private class BasicRemote extends AbstractRemoteEndpoint implements RemoteEndpoint.Basic {
+
+		@Override
+		public void sendText(String text) throws IOException {
+			dispatch(text, true);
+		}
+
+		@Override
+		public void sendBinary(ByteBuffer data) throws IOException {
+		}
+
+		@Override
+		public void sendText(String partialMessage, boolean isLast) throws IOException {
+			dispatch(partialMessage, isLast);
+		}
+
+		@Override
+		public void sendBinary(ByteBuffer partialByte, boolean isLast) throws IOException {
+		}
+
+		@Override
+		public OutputStream getSendStream() throws IOException {
+			return null;
+		}
+
+		@Override
+		public Writer getSendWriter() throws IOException {
+			return null;
+		}
+
+		@Override
+		public void sendObject(Object data) throws IOException, EncodeException {
+		}
+		
+	}
+	
+	private class AsyncRemote extends AbstractRemoteEndpoint implements RemoteEndpoint.Async {
+
+		@Override
+		public long getSendTimeout() {
+			return 1000;
+		}
+
+		@Override
+		public void setSendTimeout(long timeoutmillis) {
+		}
+
+		@Override
+		public void sendText(String text, SendHandler handler) {
+			sendText(text).thenRun(() -> {
+				handler.onResult(new SendResult());
+			});
+		}
+
+		@Override
+		public CompletableFuture<Void> sendText(String text) {
+			return CompletableFuture.runAsync(() -> {
+				dispatch(text, true);
+			});
+		}
+
+		@Override
+		public Future<Void> sendBinary(ByteBuffer data) {
+			return null;
+		}
+
+		@Override
+		public void sendBinary(ByteBuffer data, SendHandler handler) {
+		}
+
+		@Override
+		public Future<Void> sendObject(Object data) {
+			return null;
+		}
+
+		@Override
+		public void sendObject(Object data, SendHandler handler) {
+		}
+		
+	}
+	
+	private static abstract class AbstractRemoteEndpoint implements RemoteEndpoint {
+
+		@Override
+		public void setBatchingAllowed(boolean allowed) throws IOException {
+		}
+
+		@Override
+		public boolean getBatchingAllowed() {
+			return false;
+		}
+
+		@Override
+		public void flushBatch() throws IOException {
+		}
+
+		@Override
+		public void sendPing(ByteBuffer applicationData) throws IOException, IllegalArgumentException {
+		}
+
+		@Override
+		public void sendPong(ByteBuffer applicationData) throws IOException, IllegalArgumentException {
+		}
+		
+	}
+
+}