--- a/net/minecraft/network/syncher/SynchedEntityData.java
+++ b/net/minecraft/network/syncher/SynchedEntityData.java
@@ -8,6 +8,9 @@
 import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
 import it.unimi.dsi.fastutil.objects.Object2IntMap;
 import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
+import it.unimi.dsi.fastutil.objects.ObjectIterator;
+import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.Objects;
@@ -15,7 +18,6 @@
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 import javax.annotation.Nullable;
 import net.minecraft.CrashReport;
-import net.minecraft.CrashReportCategory;
 import net.minecraft.ReportedException;
 import net.minecraft.network.FriendlyByteBuf;
 import net.minecraft.world.entity.Entity;
@@ -23,13 +25,14 @@
 import org.slf4j.Logger;
 
 public class SynchedEntityData {
+
     private static final Logger LOGGER = LogUtils.getLogger();
-    private static final Object2IntMap<Class<? extends Entity>> ENTITY_ID_POOL = new Object2IntOpenHashMap<>();
+    private static final Object2IntMap<Class<? extends Entity>> ENTITY_ID_POOL = new Object2IntOpenHashMap();
     private static final int EOF_MARKER = 255;
     private static final int MAX_ID_VALUE = 254;
     private final Entity entity;
-    private final Int2ObjectMap<SynchedEntityData.DataItem<?>> itemsById = new Int2ObjectOpenHashMap<>();
-    private final ReadWriteLock lock = new ReentrantReadWriteLock();
+    private final Int2ObjectMap<SynchedEntityData.DataItem<?>> itemsById = new Int2ObjectOpenHashMap();
+    // private final ReadWriteLock lock = new ReentrantReadWriteLock(); // Spigot - not required
     private boolean isEmpty = true;
     private boolean isDirty;
 
@@ -38,27 +41,30 @@
     }
 
     public static <T> EntityDataAccessor<T> defineId(Class<? extends Entity> entityClass, EntityDataSerializer<T> dataHandler) {
-        if (LOGGER.isDebugEnabled()) {
+        if (SynchedEntityData.LOGGER.isDebugEnabled()) {
             try {
-                Class<?> class_ = Class.forName(Thread.currentThread().getStackTrace()[2].getClassName());
-                if (!class_.equals(entityClass)) {
-                    LOGGER.debug("defineId called for: {} from {}", entityClass, class_, new RuntimeException());
+                Class<?> oclass1 = Class.forName(Thread.currentThread().getStackTrace()[2].getClassName());
+
+                if (!oclass1.equals(entityClass)) {
+                    SynchedEntityData.LOGGER.debug("defineId called for: {} from {}", new Object[]{entityClass, oclass1, new RuntimeException()});
                 }
-            } catch (ClassNotFoundException var5) {
+            } catch (ClassNotFoundException classnotfoundexception) {
+                ;
             }
         }
 
         int i;
-        if (ENTITY_ID_POOL.containsKey(entityClass)) {
-            i = ENTITY_ID_POOL.getInt(entityClass) + 1;
+
+        if (SynchedEntityData.ENTITY_ID_POOL.containsKey(entityClass)) {
+            i = SynchedEntityData.ENTITY_ID_POOL.getInt(entityClass) + 1;
         } else {
             int j = 0;
-            Class<?> class2 = entityClass;
+            Class oclass2 = entityClass;
 
-            while(class2 != Entity.class) {
-                class2 = class2.getSuperclass();
-                if (ENTITY_ID_POOL.containsKey(class2)) {
-                    j = ENTITY_ID_POOL.getInt(class2) + 1;
+            while (oclass2 != Entity.class) {
+                oclass2 = oclass2.getSuperclass();
+                if (SynchedEntityData.ENTITY_ID_POOL.containsKey(oclass2)) {
+                    j = SynchedEntityData.ENTITY_ID_POOL.getInt(oclass2) + 1;
                     break;
                 }
             }
@@ -69,48 +75,61 @@
         if (i > 254) {
             throw new IllegalArgumentException("Data value id is too big with " + i + "! (Max is 254)");
         } else {
-            ENTITY_ID_POOL.put(entityClass, i);
+            SynchedEntityData.ENTITY_ID_POOL.put(entityClass, i);
             return dataHandler.createAccessor(i);
         }
     }
 
+    public boolean registrationLocked; // Spigot
     public <T> void define(EntityDataAccessor<T> key, T initialValue) {
+        if (this.registrationLocked) throw new IllegalStateException("Registering datawatcher object after entity initialization"); // Spigot
         int i = key.getId();
+
         if (i > 254) {
             throw new IllegalArgumentException("Data value id is too big with " + i + "! (Max is 254)");
         } else if (this.itemsById.containsKey(i)) {
             throw new IllegalArgumentException("Duplicate id value for " + i + "!");
         } else if (EntityDataSerializers.getSerializedId(key.getSerializer()) < 0) {
-            throw new IllegalArgumentException("Unregistered serializer " + key.getSerializer() + " for " + i + "!");
+            EntityDataSerializer datawatcherserializer = key.getSerializer();
+
+            throw new IllegalArgumentException("Unregistered serializer " + datawatcherserializer + " for " + i + "!");
         } else {
             this.createDataItem(key, initialValue);
         }
     }
 
-    private <T> void createDataItem(EntityDataAccessor<T> entityDataAccessor, T object) {
-        SynchedEntityData.DataItem<T> dataItem = new SynchedEntityData.DataItem<>(entityDataAccessor, object);
-        this.lock.writeLock().lock();
-        this.itemsById.put(entityDataAccessor.getId(), dataItem);
+    private <T> void createDataItem(EntityDataAccessor<T> datawatcherobject, T t0) {
+        SynchedEntityData.DataItem<T> datawatcher_item = new SynchedEntityData.DataItem<>(datawatcherobject, t0);
+
+        // this.lock.writeLock().lock(); // Spigot - not required
+        this.itemsById.put(datawatcherobject.getId(), datawatcher_item);
         this.isEmpty = false;
-        this.lock.writeLock().unlock();
+        // this.lock.writeLock().unlock(); // Spigot - not required
     }
 
-    private <T> SynchedEntityData.DataItem<T> getItem(EntityDataAccessor<T> entityDataAccessor) {
+    private <T> SynchedEntityData.DataItem<T> getItem(EntityDataAccessor<T> datawatcherobject) {
+        // Spigot start
+        /*
         this.lock.readLock().lock();
 
-        SynchedEntityData.DataItem<T> dataItem;
+        DataWatcher.Item datawatcher_item;
+
         try {
-            dataItem = this.itemsById.get(entityDataAccessor.getId());
-        } catch (Throwable var9) {
-            CrashReport crashReport = CrashReport.forThrowable(var9, "Getting synched entity data");
-            CrashReportCategory crashReportCategory = crashReport.addCategory("Synched entity data");
-            crashReportCategory.setDetail("Data ID", entityDataAccessor);
-            throw new ReportedException(crashReport);
+            datawatcher_item = (DataWatcher.Item) this.itemsById.get(datawatcherobject.getId());
+        } catch (Throwable throwable) {
+            CrashReport crashreport = CrashReport.forThrowable(throwable, "Getting synched entity data");
+            CrashReportSystemDetails crashreportsystemdetails = crashreport.addCategory("Synched entity data");
+
+            crashreportsystemdetails.setDetail("Data ID", (Object) datawatcherobject);
+            throw new ReportedException(crashreport);
         } finally {
             this.lock.readLock().unlock();
         }
 
-        return dataItem;
+        return datawatcher_item;
+        */
+        return (SynchedEntityData.DataItem) this.itemsById.get(datawatcherobject.getId());
+        // Spigot end
     }
 
     public <T> T get(EntityDataAccessor<T> data) {
@@ -118,24 +137,36 @@
     }
 
     public <T> void set(EntityDataAccessor<T> key, T value) {
-        SynchedEntityData.DataItem<T> dataItem = this.getItem(key);
-        if (ObjectUtils.notEqual(value, dataItem.getValue())) {
-            dataItem.setValue(value);
+        SynchedEntityData.DataItem<T> datawatcher_item = this.getItem(key);
+
+        if (ObjectUtils.notEqual(value, datawatcher_item.getValue())) {
+            datawatcher_item.setValue(value);
             this.entity.onSyncedDataUpdated(key);
-            dataItem.setDirty(true);
+            datawatcher_item.setDirty(true);
             this.isDirty = true;
         }
 
     }
 
+    // CraftBukkit start - add method from above
+    public <T> void markDirty(EntityDataAccessor<T> datawatcherobject) {
+        this.getItem(datawatcherobject).setDirty(true);
+        this.isDirty = true;
+    }
+    // CraftBukkit end
+
     public boolean isDirty() {
         return this.isDirty;
     }
 
     public static void pack(@Nullable List<SynchedEntityData.DataItem<?>> entries, FriendlyByteBuf buf) {
         if (entries != null) {
-            for(SynchedEntityData.DataItem<?> dataItem : entries) {
-                writeDataItem(buf, dataItem);
+            Iterator iterator = entries.iterator();
+
+            while (iterator.hasNext()) {
+                SynchedEntityData.DataItem<?> datawatcher_item = (SynchedEntityData.DataItem) iterator.next();
+
+                SynchedEntityData.writeDataItem(buf, datawatcher_item);
             }
         }
 
@@ -145,21 +176,25 @@
     @Nullable
     public List<SynchedEntityData.DataItem<?>> packDirty() {
         List<SynchedEntityData.DataItem<?>> list = null;
+
         if (this.isDirty) {
-            this.lock.readLock().lock();
+            // this.lock.readLock().lock(); // Spigot - not required
+            ObjectIterator objectiterator = this.itemsById.values().iterator();
 
-            for(SynchedEntityData.DataItem<?> dataItem : this.itemsById.values()) {
-                if (dataItem.isDirty()) {
-                    dataItem.setDirty(false);
+            while (objectiterator.hasNext()) {
+                SynchedEntityData.DataItem<?> datawatcher_item = (SynchedEntityData.DataItem) objectiterator.next();
+
+                if (datawatcher_item.isDirty()) {
+                    datawatcher_item.setDirty(false);
                     if (list == null) {
                         list = Lists.newArrayList();
                     }
 
-                    list.add(dataItem.copy());
+                    list.add(datawatcher_item.copy());
                 }
             }
 
-            this.lock.readLock().unlock();
+            // this.lock.readLock().unlock(); // Spigot - not required
         }
 
         this.isDirty = false;
@@ -169,71 +204,80 @@
     @Nullable
     public List<SynchedEntityData.DataItem<?>> getAll() {
         List<SynchedEntityData.DataItem<?>> list = null;
-        this.lock.readLock().lock();
 
-        for(SynchedEntityData.DataItem<?> dataItem : this.itemsById.values()) {
+        // this.lock.readLock().lock(); // Spigot - not required
+
+        SynchedEntityData.DataItem datawatcher_item;
+
+        for (ObjectIterator objectiterator = this.itemsById.values().iterator(); objectiterator.hasNext(); list.add(datawatcher_item.copy())) {
+            datawatcher_item = (SynchedEntityData.DataItem) objectiterator.next();
             if (list == null) {
                 list = Lists.newArrayList();
             }
-
-            list.add(dataItem.copy());
         }
 
-        this.lock.readLock().unlock();
+        // this.lock.readLock().unlock(); // Spigot - not required
         return list;
     }
 
     private static <T> void writeDataItem(FriendlyByteBuf buf, SynchedEntityData.DataItem<T> entry) {
-        EntityDataAccessor<T> entityDataAccessor = entry.getAccessor();
-        int i = EntityDataSerializers.getSerializedId(entityDataAccessor.getSerializer());
+        EntityDataAccessor<T> datawatcherobject = entry.getAccessor();
+        int i = EntityDataSerializers.getSerializedId(datawatcherobject.getSerializer());
+
         if (i < 0) {
-            throw new EncoderException("Unknown serializer type " + entityDataAccessor.getSerializer());
+            throw new EncoderException("Unknown serializer type " + datawatcherobject.getSerializer());
         } else {
-            buf.writeByte(entityDataAccessor.getId());
+            buf.writeByte(datawatcherobject.getId());
             buf.writeVarInt(i);
-            entityDataAccessor.getSerializer().write(buf, entry.getValue());
+            datawatcherobject.getSerializer().write(buf, entry.getValue());
         }
     }
 
     @Nullable
     public static List<SynchedEntityData.DataItem<?>> unpack(FriendlyByteBuf buf) {
-        List<SynchedEntityData.DataItem<?>> list = null;
+        ArrayList arraylist = null;
 
-        int i;
-        while((i = buf.readUnsignedByte()) != 255) {
-            if (list == null) {
-                list = Lists.newArrayList();
+        short short0;
+
+        while ((short0 = buf.readUnsignedByte()) != 255) {
+            if (arraylist == null) {
+                arraylist = Lists.newArrayList();
             }
 
-            int j = buf.readVarInt();
-            EntityDataSerializer<?> entityDataSerializer = EntityDataSerializers.getSerializer(j);
-            if (entityDataSerializer == null) {
-                throw new DecoderException("Unknown serializer type " + j);
+            int i = buf.readVarInt();
+            EntityDataSerializer<?> datawatcherserializer = EntityDataSerializers.getSerializer(i);
+
+            if (datawatcherserializer == null) {
+                throw new DecoderException("Unknown serializer type " + i);
             }
 
-            list.add(genericHelper(buf, i, entityDataSerializer));
+            arraylist.add(SynchedEntityData.genericHelper(buf, short0, datawatcherserializer));
         }
 
-        return list;
+        return arraylist;
     }
 
-    private static <T> SynchedEntityData.DataItem<T> genericHelper(FriendlyByteBuf buf, int i, EntityDataSerializer<T> entityDataSerializer) {
-        return new SynchedEntityData.DataItem<>(entityDataSerializer.createAccessor(i), entityDataSerializer.read(buf));
+    private static <T> SynchedEntityData.DataItem<T> genericHelper(FriendlyByteBuf buf, int i, EntityDataSerializer<T> datawatcherserializer) {
+        return new SynchedEntityData.DataItem<>(datawatcherserializer.createAccessor(i), datawatcherserializer.read(buf));
     }
 
     public void assignValues(List<SynchedEntityData.DataItem<?>> entries) {
-        this.lock.writeLock().lock();
+        // this.lock.writeLock().lock(); // Spigot - not required
 
         try {
-            for(SynchedEntityData.DataItem<?> dataItem : entries) {
-                SynchedEntityData.DataItem<?> dataItem2 = this.itemsById.get(dataItem.getAccessor().getId());
-                if (dataItem2 != null) {
-                    this.assignValue(dataItem2, dataItem);
-                    this.entity.onSyncedDataUpdated(dataItem.getAccessor());
+            Iterator iterator = entries.iterator();
+
+            while (iterator.hasNext()) {
+                SynchedEntityData.DataItem<?> datawatcher_item = (SynchedEntityData.DataItem) iterator.next();
+                SynchedEntityData.DataItem<?> datawatcher_item1 = (SynchedEntityData.DataItem) this.itemsById.get(datawatcher_item.getAccessor().getId());
+
+                if (datawatcher_item1 != null) {
+                    this.assignValue(datawatcher_item1, datawatcher_item);
+                    this.entity.onSyncedDataUpdated(datawatcher_item.getAccessor());
                 }
             }
         } finally {
-            this.lock.writeLock().unlock();
+            // this.lock.writeLock().unlock(); // Spigot - not required
         }
 
         this.isDirty = true;
@@ -243,7 +287,7 @@
         if (!Objects.equals(from.accessor.getSerializer(), to.accessor.getSerializer())) {
             throw new IllegalStateException(String.format(Locale.ROOT, "Invalid entity data item type for field %d on entity %s: old=%s(%s), new=%s(%s)", to.accessor.getId(), this.entity, to.value, to.value.getClass(), from.value, from.value.getClass()));
         } else {
-            to.setValue((T)from.getValue());
+            to.setValue((T) from.getValue()); // CraftBukkit - decompile error
         }
     }
 
@@ -253,16 +297,20 @@
 
     public void clearDirty() {
         this.isDirty = false;
-        this.lock.readLock().lock();
+        // this.lock.readLock().lock(); // Spigot - not required
+        ObjectIterator objectiterator = this.itemsById.values().iterator();
 
-        for(SynchedEntityData.DataItem<?> dataItem : this.itemsById.values()) {
-            dataItem.setDirty(false);
+        while (objectiterator.hasNext()) {
+            SynchedEntityData.DataItem<?> datawatcher_item = (SynchedEntityData.DataItem) objectiterator.next();
+
+            datawatcher_item.setDirty(false);
         }
 
-        this.lock.readLock().unlock();
+        // this.lock.readLock().unlock(); // Spigot - not required
     }
 
     public static class DataItem<T> {
+
         final EntityDataAccessor<T> accessor;
         T value;
         private boolean dirty;
