diff --git a/Spigot-API-Patches/Player-Tab-List-and-Title-APIs.patch b/Spigot-API-Patches/Player-Tab-List-and-Title-APIs.patch
index d415d526c9..1f9cf677fc 100644
--- a/Spigot-API-Patches/Player-Tab-List-and-Title-APIs.patch
+++ b/Spigot-API-Patches/Player-Tab-List-and-Title-APIs.patch
@@ -1,5 +1,5 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Jedediah Smith <jedediah@silencegreys.com>
+From: Techcable <Techcable@outlook.com>
 Date: Tue, 16 Feb 2016 19:51:11 -0600
 Subject: [PATCH] Player Tab List and Title APIs
 
@@ -8,6 +8,16 @@ diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/buk
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/entity/Player.java
 +++ b/src/main/java/org/bukkit/entity/Player.java
+@@ -0,0 +0,0 @@ import org.bukkit.conversations.Conversable;
+ import org.bukkit.map.MapView;
+ import org.bukkit.plugin.messaging.PluginMessageRecipient;
+ import org.bukkit.scoreboard.Scoreboard;
++// PaperSpigot start
++import org.github.paperspigot.Title;
++// PaperSpigot end
+ 
+ /**
+  * Represents a player, connected or not
 @@ -0,0 +0,0 @@ public interface Player extends HumanEntity, Conversable, CommandSender, Offline
       * @param components the components to send
       */
@@ -30,32 +40,42 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    public void setPlayerListHeaderFooter(net.md_5.bungee.api.chat.BaseComponent header, net.md_5.bungee.api.chat.BaseComponent footer);
 +
 +    /**
-+     * Set the times for titles displayed to the player
++     * Update the times for titles displayed to the player
 +     *
 +     * @param fadeInTicks  ticks to fade-in
 +     * @param stayTicks    ticks to stay visible
 +     * @param fadeOutTicks ticks to fade-out
++     * @deprecated Use {@link #updateTitle(Title)}
 +     */
++    @Deprecated
 +    public void setTitleTimes(int fadeInTicks, int stayTicks, int fadeOutTicks);
 +
 +    /**
-+     * Set the subtitle of titles displayed to the player
++     * Update the subtitle of titles displayed to the player
++     * @deprecated Use {@link #updateTitle(Title)}
 +     */
++    @Deprecated
 +    public void setSubtitle(net.md_5.bungee.api.chat.BaseComponent[] subtitle);
 +
 +    /**
-+     * Set the subtitle of titles displayed to the player
++     * Update the subtitle of titles displayed to the player
++     * @deprecated Use {@link #updateTitle(Title)}
 +     */
++    @Deprecated
 +    public void setSubtitle(net.md_5.bungee.api.chat.BaseComponent subtitle);
 +
 +    /**
 +     * Show the given title to the player, along with the last subtitle set, using the last set times
++     * @deprecated Use {@link #sendTitle(Title)} or {@link #updateTitle(Title)}
 +     */
++    @Deprecated
 +    public void showTitle(net.md_5.bungee.api.chat.BaseComponent[] title);
 +
 +    /**
 +     * Show the given title to the player, along with the last subtitle set, using the last set times
++     * @deprecated Use {@link #sendTitle(Title)} or {@link #updateTitle(Title)}
 +     */
++    @Deprecated
 +    public void showTitle(net.md_5.bungee.api.chat.BaseComponent title);
 +
 +    /**
@@ -66,7 +86,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param fadeInTicks  ticks to fade-in
 +     * @param stayTicks    ticks to stay visible
 +     * @param fadeOutTicks ticks to fade-out
++     * @deprecated Use {@link #sendTitle(Title)} or {@link #updateTitle(Title)}
 +     */
++    @Deprecated
 +    public void showTitle(net.md_5.bungee.api.chat.BaseComponent[] title, net.md_5.bungee.api.chat.BaseComponent[] subtitle, int fadeInTicks, int stayTicks, int fadeOutTicks);
 +
 +    /**
@@ -77,10 +99,32 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param fadeInTicks  ticks to fade-in
 +     * @param stayTicks    ticks to stay visible
 +     * @param fadeOutTicks ticks to fade-out
++     * @deprecated Use {@link #sendTitle(Title)} or {@link #updateTitle(Title)}
 +     */
++    @Deprecated
 +    public void showTitle(net.md_5.bungee.api.chat.BaseComponent title, net.md_5.bungee.api.chat.BaseComponent subtitle, int fadeInTicks, int stayTicks, int fadeOutTicks);
 +
 +    /**
++     * Show the title to the player, overriding any previously displayed title.
++     *
++     * <p>This method overrides any previous title, use {@link #updateTitle(Title)} to change the existing one.</p>
++     *
++     * @param title the title to send
++     * @throws NullPointerException if the title is null
++     */
++    void sendTitle(Title title);
++
++    /**
++     * Show the title to the player, overriding any previously displayed title.
++     *
++     * <p>This method doesn't override previous titles, but changes their values.</p>
++     *
++     * @param title the title to send
++     * @throws NullPointerException if title is null
++     */
++    void updateTitle(Title title);
++
++    /**
 +     * Hide any title that is currently visible to the player
 +     */
 +    public void hideTitle();
@@ -98,4 +142,369 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      public void resetTitle();
  
      // Spigot start
+diff --git a/src/main/java/org/github/paperspigot/Title.java b/src/main/java/org/github/paperspigot/Title.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/org/github/paperspigot/Title.java
+@@ -0,0 +0,0 @@
++package org.github.paperspigot;
++
++import net.md_5.bungee.api.chat.BaseComponent;
++import net.md_5.bungee.api.chat.TextComponent;
++
++import org.bukkit.entity.Player;
++
++import static com.google.common.base.Preconditions.checkArgument;
++import static com.google.common.base.Preconditions.checkNotNull;
++import static com.google.common.base.Preconditions.checkState;
++
++/**
++ * Represents a title to may be sent to a {@link Player}.
++ * <p>
++ * <p>A title can be sent without subtitle text.</p>
++ */
++public final class Title {
++
++    /**
++     * The default number of ticks for the title to fade in.
++     */
++    public static final int DEFAULT_FADE_IN = 20;
++    /**
++     * The default number of ticks for the title to stay.
++     */
++    public static final int DEFAULT_STAY = 200;
++    /**
++     * The default number of ticks for the title to fade out.
++     */
++    public static final int DEFAULT_FADE_OUT = 20;
++
++    private final BaseComponent[] title;
++    private final BaseComponent[] subtitle;
++    private final int fadeIn;
++    private final int stay;
++    private final int fadeOut;
++
++    /**
++     * Create a title with the default time values and no subtitle.
++     * <p>
++     * <p>Times use default values.</p>
++     *
++     * @param title the main text of the title
++     * @throws NullPointerException if the title is null
++     */
++    public Title(BaseComponent title) {
++        this(title, null);
++    }
++
++    /**
++     * Create a title with the default time values and no subtitle.
++     * <p>
++     * <p>Times use default values.</p>
++     *
++     * @param title the main text of the title
++     * @throws NullPointerException if the title is null
++     */
++    public Title(BaseComponent[] title) {
++        this(title, null);
++    }
++
++    /**
++     * Create a title with the default time values and no subtitle.
++     * <p>
++     * <p>Times use default values.</p>
++     *
++     * @param title the main text of the title
++     * @throws NullPointerException if the title is null
++     */
++    public Title(String title) {
++        this(title, null);
++    }
++
++    /**
++     * Create a title with the default time values.
++     * <p>
++     * <p>Times use default values.</p>
++     *
++     * @param title    the main text of the title
++     * @param subtitle the secondary text of the title
++     */
++    public Title(BaseComponent title, BaseComponent subtitle) {
++        this(title, subtitle, DEFAULT_FADE_IN, DEFAULT_STAY, DEFAULT_FADE_OUT);
++    }
++
++    /**
++     * Create a title with the default time values.
++     * <p>
++     * <p>Times use default values.</p>
++     *
++     * @param title    the main text of the title
++     * @param subtitle the secondary text of the title
++     */
++    public Title(BaseComponent[] title, BaseComponent[] subtitle) {
++        this(title, subtitle, DEFAULT_FADE_IN, DEFAULT_STAY, DEFAULT_FADE_OUT);
++    }
++
++    /**
++     * Create a title with the default time values.
++     * <p>
++     * <p>Times use default values.</p>
++     *
++     * @param title    the main text of the title
++     * @param subtitle the secondary text of the title
++     */
++    public Title(String title, String subtitle) {
++        this(title, subtitle, DEFAULT_FADE_IN, DEFAULT_STAY, DEFAULT_FADE_OUT);
++    }
++
++    /**
++     * Creates a new title.
++     *
++     * @param title    the main text of the title
++     * @param subtitle the secondary text of the title
++     * @param fadeIn   the number of ticks for the title to fade in
++     * @param stay     the number of ticks for the title to stay on screen
++     * @param fadeOut  the number of ticks for the title to fade out
++     * @throws IllegalArgumentException if any of the times are negative
++     */
++    public Title(BaseComponent title, BaseComponent subtitle, int fadeIn, int stay, int fadeOut) {
++        this(
++                new BaseComponent[]{checkNotNull(title, "title")},
++                subtitle == null ? null : new BaseComponent[]{subtitle},
++                fadeIn,
++                stay,
++                fadeOut
++        );
++    }
++
++    /**
++     * Creates a new title.
++     *
++     * @param title    the main text of the title
++     * @param subtitle the secondary text of the title
++     * @param fadeIn   the number of ticks for the title to fade in
++     * @param stay     the number of ticks for the title to stay on screen
++     * @param fadeOut  the number of ticks for the title to fade out
++     * @throws IllegalArgumentException if any of the times are negative
++     */
++    public Title(BaseComponent[] title, BaseComponent[] subtitle, int fadeIn, int stay, int fadeOut) {
++        checkArgument(fadeIn >= 0, "Negative fadeIn: %s", fadeIn);
++        checkArgument(stay >= 0, "Negative stay: %s", stay);
++        checkArgument(fadeOut >= 0, "Negative fadeOut: %s", fadeOut);
++        this.title = checkNotNull(title, "title");
++        this.subtitle = subtitle;
++        this.fadeIn = fadeIn;
++        this.stay = stay;
++        this.fadeOut = fadeOut;
++    }
++
++    /**
++     * Creates a new title.
++     * <p>
++     * <p>It is recommended to the {@link BaseComponent} constrctors.</p>
++     *
++     * @param title    the main text of the title
++     * @param subtitle the secondary text of the title
++     * @param fadeIn   the number of ticks for the title to fade in
++     * @param stay     the number of ticks for the title to stay on screen
++     * @param fadeOut  the number of ticks for the title to fade out
++     */
++    public Title(String title, String subtitle, int fadeIn, int stay, int fadeOut) {
++        this(
++                TextComponent.fromLegacyText(checkNotNull(title, "title")),
++                subtitle == null ? null : TextComponent.fromLegacyText(subtitle),
++                fadeIn,
++                stay,
++                fadeOut
++        );
++    }
++
++    /**
++     * Gets the text of this title
++     *
++     * @return the text
++     */
++    public BaseComponent[] getTitle() {
++        return this.title;
++    }
++
++    /**
++     * Gets the text of this title's subtitle
++     *
++     * @return the text
++     */
++    public BaseComponent[] getSubtitle() {
++        return this.subtitle;
++    }
++
++    /**
++     * Gets the number of ticks to fade in.
++     * <p>
++     * <p>The returned value is never negative.</p>
++     *
++     * @return the number of ticks to fade in
++     */
++    public int getFadeIn() {
++        return this.fadeIn;
++    }
++
++    /**
++     * Gets the number of ticks to stay.
++     * <p>
++     * <p>The returned value is never negative.</p>
++     *
++     * @return the number of ticks to stay
++     */
++    public int getStay() {
++        return this.stay;
++    }
++
++    /**
++     * Gets the number of ticks to fade out.
++     * <p>
++     * <p>The returned value is never negative.</p>
++     *
++     * @return the number of ticks to fade out
++     */
++    public int getFadeOut() {
++        return this.fadeOut;
++    }
++
++    public static Builder builder() {
++        return new Builder();
++    }
++
++    /**
++     * A builder for creating titles
++     */
++    public static final class Builder {
++
++        private BaseComponent[] title;
++        private BaseComponent[] subtitle;
++        private int fadeIn = DEFAULT_FADE_IN;
++        private int stay = DEFAULT_STAY;
++        private int fadeOut = DEFAULT_FADE_OUT;
++
++        /**
++         * Sets the title to the given text.
++         *
++         * @param title the title text
++         * @return this builder instance
++         * @throws NullPointerException if the title is null
++         */
++        public Builder title(BaseComponent title) {
++            return this.title(new BaseComponent[]{checkNotNull(title, "title")});
++        }
++
++        /**
++         * Sets the title to the given text.
++         *
++         * @param title the title text
++         * @return this builder instance
++         * @throws NullPointerException if the title is null
++         */
++        public Builder title(BaseComponent[] title) {
++            this.title = checkNotNull(title, "title");
++            return this;
++        }
++
++        /**
++         * Sets the title to the given text.
++         * <p>
++         * <p>It is recommended to the {@link BaseComponent} methods.</p>
++         *
++         * @param title the title text
++         * @return this builder instance
++         * @throws NullPointerException if the title is null
++         */
++        public Builder title(String title) {
++            return this.title(TextComponent.fromLegacyText(checkNotNull(title, "title")));
++        }
++
++        /**
++         * Sets the subtitle to the given text.
++         *
++         * @param subtitle the title text
++         * @return this builder instance
++         */
++        public Builder subtitle(BaseComponent subtitle) {
++            return this.subtitle(subtitle == null ? null : new BaseComponent[]{subtitle});
++        }
++
++        /**
++         * Sets the subtitle to the given text.
++         *
++         * @param subtitle the title text
++         * @return this builder instance
++         */
++        public Builder subtitle(BaseComponent[] subtitle) {
++            this.subtitle = subtitle;
++            return this;
++        }
++
++        /**
++         * Sets the subtitle to the given text.
++         * <p>
++         * <p>It is recommended to the {@link BaseComponent} methods.</p>
++         *
++         * @param subtitle the title text
++         * @return this builder instance
++         */
++        public Builder subtitle(String subtitle) {
++            return this.subtitle(subtitle == null ? null : TextComponent.fromLegacyText(subtitle));
++        }
++
++        /**
++         * Sets the number of ticks for the title to fade in
++         *
++         * @param fadeIn the number of ticks to fade in
++         * @return this builder instance
++         * @throws IllegalArgumentException if it is negative
++         */
++        public Builder fadeIn(int fadeIn) {
++            checkArgument(fadeIn >= 0, "Negative fadeIn: %s", fadeIn);
++            this.fadeIn = fadeIn;
++            return this;
++        }
++
++
++        /**
++         * Sets the number of ticks for the title to stay.
++         *
++         * @param stay the number of ticks to stay
++         * @return this builder instance
++         * @throws IllegalArgumentException if it is negative
++         */
++        public Builder stay(int stay) {
++            checkArgument(stay >= 0, "Negative stay: %s", stay);
++            this.stay = stay;
++            return this;
++        }
++
++        /**
++         * Sets the number of ticks for the title to fade out.
++         *
++         * @param fadeOut the number of ticks to fade out
++         * @return this builder instance
++         * @throws IllegalArgumentException if it is negative
++         */
++        public Builder fadeOut(int fadeOut) {
++            checkArgument(fadeOut >= 0, "Negative fadeOut: %s", fadeOut);
++            this.fadeOut = fadeOut;
++            return this;
++        }
++
++        /**
++         * Create a title based on the values in the builder.
++         *
++         * @return a title from the values in this builder
++         * @throws IllegalStateException if title isn't specified
++         */
++        public Title build() {
++            checkState(title != null, "Title not specified");
++            return new Title(this.title, this.subtitle, this.fadeIn, this.stay, this.fadeOut);
++        }
++    }
++}
+\ No newline at end of file
 --
\ No newline at end of file
diff --git a/Spigot-Server-Patches/Player-Tab-List-and-Title-APIs.patch b/Spigot-Server-Patches/Player-Tab-List-and-Title-APIs.patch
index 5bde47edab..b41319093b 100644
--- a/Spigot-Server-Patches/Player-Tab-List-and-Title-APIs.patch
+++ b/Spigot-Server-Patches/Player-Tab-List-and-Title-APIs.patch
@@ -1,5 +1,5 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Jedediah Smith <jedediah@silencegreys.com>
+From: Techcable <Techcable@outlook.com>
 Date: Tue, 16 Feb 2016 19:45:55 -0600
 Subject: [PATCH] Player Tab List and Title APIs
 
@@ -41,10 +41,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      public void a(PacketListenerPlayOut packetlistenerplayout) {
          packetlistenerplayout.a(this);
      }
--
--    public void a(PacketListener packetlistener) {
--        this.a((PacketListenerPlayOut) packetlistener);
--    }
+ 
++    // PaperSpigot start - fix compile error
++    /*
+     public void a(PacketListener packetlistener) {
+         this.a((PacketListenerPlayOut) packetlistener);
+     }
++    */
++    // PaperSpigot end
  }
 diff --git a/src/main/java/net/minecraft/server/PacketPlayOutTitle.java b/src/main/java/net/minecraft/server/PacketPlayOutTitle.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
@@ -88,17 +92,30 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          packetlistenerplayout.a(this);
      }
  
--    public void a(PacketListener packetlistener) {
--        this.a((PacketListenerPlayOut) packetlistener);
--    }
--
++    // PaperSpigot start - fix compile error
++    /*
+     public void a(PacketListener packetlistener) {
+         this.a((PacketListenerPlayOut) packetlistener);
+     }
++    */
++    // PaperSpigot end
+ 
      public static enum EnumTitleAction {
  
-         TITLE, SUBTITLE, TIMES, CLEAR, RESET;
 diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
 +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+@@ -0,0 +0,0 @@ import org.bukkit.metadata.MetadataValue;
+ import org.bukkit.plugin.Plugin;
+ import org.bukkit.plugin.messaging.StandardMessenger;
+ import org.bukkit.scoreboard.Scoreboard;
++// PaperSpigot start
++import org.github.paperspigot.Title;
++// PaperSpigot end
+ 
+ @DelegateDeserialization(CraftOfflinePlayer.class)
+ public class CraftPlayer extends CraftHumanEntity implements Player {
 @@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
          packet.components = components;
          getHandle().playerConnection.sendPacket(packet);
@@ -159,6 +176,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
++    public void sendTitle(Title title) {
++        Preconditions.checkNotNull(title, "Title is null");
++        setTitleTimes(title.getFadeIn(), title.getStay(), title.getFadeOut());
++        setSubtitle(title.getSubtitle() == null ? new BaseComponent[0] : title.getSubtitle());
++        showTitle(title.getTitle());
++    }
++
++    @Override
++    public void updateTitle(Title title) {
++        Preconditions.checkNotNull(title, "Title is null");
++        setTitleTimes(title.getFadeIn(), title.getStay(), title.getFadeOut());
++        if (title.getSubtitle() != null) {
++            setSubtitle(title.getSubtitle());
++        }
++        showTitle(title.getTitle());
++    }
++
++    @Override
 +    public void hideTitle() {
 +        getHandle().playerConnection.sendPacket(new PacketPlayOutTitle(PacketPlayOutTitle.EnumTitleAction.CLEAR, (BaseComponent[]) null, 0, 0, 0));
 +    }