--- a/net/minecraft/server/ServerScoreboard.java
+++ b/net/minecraft/server/ServerScoreboard.java
@@ -2,7 +2,9 @@
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
 import javax.annotation.Nullable;
@@ -27,6 +29,7 @@
 import net.minecraft.world.scores.ScoreboardSaveData;
 
 public class ServerScoreboard extends Scoreboard {
+
     private final MinecraftServer server;
     private final Set<Objective> trackedObjectives = Sets.newHashSet();
     private final List<Runnable> dirtyListeners = Lists.newArrayList();
@@ -39,17 +42,7 @@
     protected void onScoreChanged(ScoreHolder scoreHolder, Objective objective, Score score) {
         super.onScoreChanged(scoreHolder, objective, score);
         if (this.trackedObjectives.contains(objective)) {
-            this.server
-                .getPlayerList()
-                .broadcastAll(
-                    new ClientboundSetScorePacket(
-                        scoreHolder.getScoreboardName(),
-                        objective.getName(),
-                        score.value(),
-                        Optional.ofNullable(score.display()),
-                        Optional.ofNullable(score.numberFormat())
-                    )
-                );
+            this.broadcastAll(new ClientboundSetScorePacket(scoreHolder.getScoreboardName(), objective.getName(), score.value(), Optional.ofNullable(score.display()), Optional.ofNullable(score.numberFormat()))); // CraftBukkit
         }
 
         this.setDirty();
@@ -64,7 +57,7 @@
     @Override
     public void onPlayerRemoved(ScoreHolder scoreHolder) {
         super.onPlayerRemoved(scoreHolder);
-        this.server.getPlayerList().broadcastAll(new ClientboundResetScorePacket(scoreHolder.getScoreboardName(), null));
+        this.broadcastAll(new ClientboundResetScorePacket(scoreHolder.getScoreboardName(), (String) null)); // CraftBukkit
         this.setDirty();
     }
 
@@ -72,7 +65,7 @@
     public void onPlayerScoreRemoved(ScoreHolder scoreHolder, Objective objective) {
         super.onPlayerScoreRemoved(scoreHolder, objective);
         if (this.trackedObjectives.contains(objective)) {
-            this.server.getPlayerList().broadcastAll(new ClientboundResetScorePacket(scoreHolder.getScoreboardName(), objective.getName()));
+            this.broadcastAll(new ClientboundResetScorePacket(scoreHolder.getScoreboardName(), objective.getName())); // CraftBukkit
         }
 
         this.setDirty();
@@ -80,19 +73,20 @@
 
     @Override
     public void setDisplayObjective(DisplaySlot slot, @Nullable Objective objective) {
-        Objective objective2 = this.getDisplayObjective(slot);
+        Objective scoreboardobjective1 = this.getDisplayObjective(slot);
+
         super.setDisplayObjective(slot, objective);
-        if (objective2 != objective && objective2 != null) {
-            if (this.getObjectiveDisplaySlotCount(objective2) > 0) {
-                this.server.getPlayerList().broadcastAll(new ClientboundSetDisplayObjectivePacket(slot, objective));
+        if (scoreboardobjective1 != objective && scoreboardobjective1 != null) {
+            if (this.getObjectiveDisplaySlotCount(scoreboardobjective1) > 0) {
+                this.broadcastAll(new ClientboundSetDisplayObjectivePacket(slot, objective)); // CraftBukkit
             } else {
-                this.stopTrackingObjective(objective2);
+                this.stopTrackingObjective(scoreboardobjective1);
             }
         }
 
         if (objective != null) {
             if (this.trackedObjectives.contains(objective)) {
-                this.server.getPlayerList().broadcastAll(new ClientboundSetDisplayObjectivePacket(slot, objective));
+                this.broadcastAll(new ClientboundSetDisplayObjectivePacket(slot, objective)); // CraftBukkit
             } else {
                 this.startTrackingObjective(objective);
             }
@@ -104,24 +98,50 @@
     @Override
     public boolean addPlayerToTeam(String scoreHolderName, PlayerTeam team) {
         if (super.addPlayerToTeam(scoreHolderName, team)) {
-            this.server
-                .getPlayerList()
-                .broadcastAll(ClientboundSetPlayerTeamPacket.createPlayerPacket(team, scoreHolderName, ClientboundSetPlayerTeamPacket.Action.ADD));
+            this.broadcastAll(ClientboundSetPlayerTeamPacket.createPlayerPacket(team, scoreHolderName, ClientboundSetPlayerTeamPacket.Action.ADD)); // CraftBukkit
+            this.setDirty();
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    // Paper start - Multiple Entries with Scoreboards
+    public boolean addPlayersToTeam(java.util.Collection<String> players, PlayerTeam team) {
+        boolean anyAdded = false;
+        for (String playerName : players) {
+            if (super.addPlayerToTeam(playerName, team)) {
+                anyAdded = true;
+            }
+        }
+
+        if (anyAdded) {
+            this.broadcastAll(ClientboundSetPlayerTeamPacket.createMultiplePlayerPacket(team, players, ClientboundSetPlayerTeamPacket.Action.ADD));
             this.setDirty();
             return true;
         } else {
             return false;
         }
     }
+    // Paper end - Multiple Entries with Scoreboards
 
     @Override
     public void removePlayerFromTeam(String scoreHolderName, PlayerTeam team) {
         super.removePlayerFromTeam(scoreHolderName, team);
-        this.server
-            .getPlayerList()
-            .broadcastAll(ClientboundSetPlayerTeamPacket.createPlayerPacket(team, scoreHolderName, ClientboundSetPlayerTeamPacket.Action.REMOVE));
+        this.broadcastAll(ClientboundSetPlayerTeamPacket.createPlayerPacket(team, scoreHolderName, ClientboundSetPlayerTeamPacket.Action.REMOVE)); // CraftBukkit
+        this.setDirty();
+    }
+
+    // Paper start - Multiple Entries with Scoreboards
+    public void removePlayersFromTeam(java.util.Collection<String> players, PlayerTeam team) {
+        for (String playerName : players) {
+            super.removePlayerFromTeam(playerName, team);
+        }
+
+        this.broadcastAll(ClientboundSetPlayerTeamPacket.createMultiplePlayerPacket(team, players, ClientboundSetPlayerTeamPacket.Action.REMOVE));
         this.setDirty();
     }
+    // Paper end - Multiple Entries with Scoreboards
 
     @Override
     public void onObjectiveAdded(Objective objective) {
@@ -133,7 +153,7 @@
     public void onObjectiveChanged(Objective objective) {
         super.onObjectiveChanged(objective);
         if (this.trackedObjectives.contains(objective)) {
-            this.server.getPlayerList().broadcastAll(new ClientboundSetObjectivePacket(objective, 2));
+            this.broadcastAll(new ClientboundSetObjectivePacket(objective, 2)); // CraftBukkit
         }
 
         this.setDirty();
@@ -152,21 +172,21 @@
     @Override
     public void onTeamAdded(PlayerTeam team) {
         super.onTeamAdded(team);
-        this.server.getPlayerList().broadcastAll(ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(team, true));
+        this.broadcastAll(ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(team, true)); // CraftBukkit
         this.setDirty();
     }
 
     @Override
     public void onTeamChanged(PlayerTeam team) {
         super.onTeamChanged(team);
-        this.server.getPlayerList().broadcastAll(ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(team, false));
+        this.broadcastAll(ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(team, false)); // CraftBukkit
         this.setDirty();
     }
 
     @Override
     public void onTeamRemoved(PlayerTeam team) {
         super.onTeamRemoved(team);
-        this.server.getPlayerList().broadcastAll(ClientboundSetPlayerTeamPacket.createRemovePacket(team));
+        this.broadcastAll(ClientboundSetPlayerTeamPacket.createRemovePacket(team)); // CraftBukkit
         this.setDirty();
     }
 
@@ -175,31 +195,37 @@
     }
 
     protected void setDirty() {
-        for (Runnable runnable : this.dirtyListeners) {
+        Iterator iterator = this.dirtyListeners.iterator();
+
+        while (iterator.hasNext()) {
+            Runnable runnable = (Runnable) iterator.next();
+
             runnable.run();
         }
+
     }
 
     public List<Packet<?>> getStartTrackingPackets(Objective objective) {
         List<Packet<?>> list = Lists.newArrayList();
+
         list.add(new ClientboundSetObjectivePacket(objective, 0));
+        DisplaySlot[] adisplayslot = DisplaySlot.values();
+        int i = adisplayslot.length;
 
-        for (DisplaySlot displaySlot : DisplaySlot.values()) {
-            if (this.getDisplayObjective(displaySlot) == objective) {
-                list.add(new ClientboundSetDisplayObjectivePacket(displaySlot, objective));
+        for (int j = 0; j < i; ++j) {
+            DisplaySlot displayslot = adisplayslot[j];
+
+            if (this.getDisplayObjective(displayslot) == objective) {
+                list.add(new ClientboundSetDisplayObjectivePacket(displayslot, objective));
             }
         }
 
-        for (PlayerScoreEntry playerScoreEntry : this.listPlayerScores(objective)) {
-            list.add(
-                new ClientboundSetScorePacket(
-                    playerScoreEntry.owner(),
-                    objective.getName(),
-                    playerScoreEntry.value(),
-                    Optional.ofNullable(playerScoreEntry.display()),
-                    Optional.ofNullable(playerScoreEntry.numberFormatOverride())
-                )
-            );
+        Iterator iterator = this.listPlayerScores(objective).iterator();
+
+        while (iterator.hasNext()) {
+            PlayerScoreEntry playerscoreentry = (PlayerScoreEntry) iterator.next();
+
+            list.add(new ClientboundSetScorePacket(playerscoreentry.owner(), objective.getName(), playerscoreentry.value(), Optional.ofNullable(playerscoreentry.display()), Optional.ofNullable(playerscoreentry.numberFormatOverride())));
         }
 
         return list;
@@ -207,10 +233,17 @@
 
     public void startTrackingObjective(Objective objective) {
         List<Packet<?>> list = this.getStartTrackingPackets(objective);
+        Iterator iterator = this.server.getPlayerList().getPlayers().iterator();
 
-        for (ServerPlayer serverPlayer : this.server.getPlayerList().getPlayers()) {
-            for (Packet<?> packet : list) {
-                serverPlayer.connection.send(packet);
+        while (iterator.hasNext()) {
+            ServerPlayer entityplayer = (ServerPlayer) iterator.next();
+            if (entityplayer.getBukkitEntity().getScoreboard().getHandle() != this) continue; // CraftBukkit - Only players on this board
+            Iterator iterator1 = list.iterator();
+
+            while (iterator1.hasNext()) {
+                Packet<?> packet = (Packet) iterator1.next();
+
+                entityplayer.connection.send(packet);
             }
         }
 
@@ -219,11 +252,16 @@
 
     public List<Packet<?>> getStopTrackingPackets(Objective objective) {
         List<Packet<?>> list = Lists.newArrayList();
+
         list.add(new ClientboundSetObjectivePacket(objective, 1));
+        DisplaySlot[] adisplayslot = DisplaySlot.values();
+        int i = adisplayslot.length;
 
-        for (DisplaySlot displaySlot : DisplaySlot.values()) {
-            if (this.getDisplayObjective(displaySlot) == objective) {
-                list.add(new ClientboundSetDisplayObjectivePacket(displaySlot, objective));
+        for (int j = 0; j < i; ++j) {
+            DisplaySlot displayslot = adisplayslot[j];
+
+            if (this.getDisplayObjective(displayslot) == objective) {
+                list.add(new ClientboundSetDisplayObjectivePacket(displayslot, objective));
             }
         }
 
@@ -232,10 +270,17 @@
 
     public void stopTrackingObjective(Objective objective) {
         List<Packet<?>> list = this.getStopTrackingPackets(objective);
+        Iterator iterator = this.server.getPlayerList().getPlayers().iterator();
 
-        for (ServerPlayer serverPlayer : this.server.getPlayerList().getPlayers()) {
-            for (Packet<?> packet : list) {
-                serverPlayer.connection.send(packet);
+        while (iterator.hasNext()) {
+            ServerPlayer entityplayer = (ServerPlayer) iterator.next();
+            if (entityplayer.getBukkitEntity().getScoreboard().getHandle() != this) continue; // CraftBukkit - Only players on this board
+            Iterator iterator1 = list.iterator();
+
+            while (iterator1.hasNext()) {
+                Packet<?> packet = (Packet) iterator1.next();
+
+                entityplayer.connection.send(packet);
             }
         }
 
@@ -244,10 +289,14 @@
 
     public int getObjectiveDisplaySlotCount(Objective objective) {
         int i = 0;
+        DisplaySlot[] adisplayslot = DisplaySlot.values();
+        int j = adisplayslot.length;
 
-        for (DisplaySlot displaySlot : DisplaySlot.values()) {
-            if (this.getDisplayObjective(displaySlot) == objective) {
-                i++;
+        for (int k = 0; k < j; ++k) {
+            DisplaySlot displayslot = adisplayslot[k];
+
+            if (this.getDisplayObjective(displayslot) == objective) {
+                ++i;
             }
         }
 
@@ -259,17 +308,31 @@
     }
 
     private ScoreboardSaveData createData() {
-        ScoreboardSaveData scoreboardSaveData = new ScoreboardSaveData(this);
-        this.addDirtyListener(scoreboardSaveData::setDirty);
-        return scoreboardSaveData;
+        ScoreboardSaveData persistentscoreboard = new ScoreboardSaveData(this);
+
+        Objects.requireNonNull(persistentscoreboard);
+        this.addDirtyListener(persistentscoreboard::setDirty);
+        return persistentscoreboard;
     }
 
     private ScoreboardSaveData createData(CompoundTag nbt, HolderLookup.Provider registryLookup) {
         return this.createData().load(nbt, registryLookup);
     }
 
+    // CraftBukkit start - Send to players
+    private void broadcastAll(Packet packet) {
+        for (ServerPlayer entityplayer : (List<ServerPlayer>) this.server.getPlayerList().players) {
+            if (entityplayer.getBukkitEntity().getScoreboard().getHandle() == this) {
+                entityplayer.connection.send(packet);
+            }
+        }
+    }
+    // CraftBukkit end
+
     public static enum Method {
-        CHANGE,
-        REMOVE;
+
+        CHANGE, REMOVE;
+
+        private Method() {}
     }
 }
