--- a/net/minecraft/commands/arguments/blocks/BlockStateParser.java
+++ b/net/minecraft/commands/arguments/blocks/BlockStateParser.java
@@ -10,10 +10,11 @@
 import com.mojang.brigadier.suggestion.Suggestions;
 import com.mojang.brigadier.suggestion.SuggestionsBuilder;
 import com.mojang.datafixers.util.Either;
+import java.util.Iterator;
 import java.util.Locale;
 import java.util.Map;
-import java.util.Optional;
 import java.util.Map.Entry;
+import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 import java.util.function.Function;
 import javax.annotation.Nullable;
@@ -34,30 +35,27 @@
 import net.minecraft.world.level.block.state.properties.Property;
 
 public class BlockStateParser {
-    public static final SimpleCommandExceptionType ERROR_NO_TAGS_ALLOWED = new SimpleCommandExceptionType(
-        Component.translatable("argument.block.tag.disallowed")
-    );
-    public static final DynamicCommandExceptionType ERROR_UNKNOWN_BLOCK = new DynamicCommandExceptionType(
-        block -> Component.translatableEscape("argument.block.id.invalid", block)
-    );
-    public static final Dynamic2CommandExceptionType ERROR_UNKNOWN_PROPERTY = new Dynamic2CommandExceptionType(
-        (block, property) -> Component.translatableEscape("argument.block.property.unknown", block, property)
-    );
-    public static final Dynamic2CommandExceptionType ERROR_DUPLICATE_PROPERTY = new Dynamic2CommandExceptionType(
-        (block, property) -> Component.translatableEscape("argument.block.property.duplicate", property, block)
-    );
-    public static final Dynamic3CommandExceptionType ERROR_INVALID_VALUE = new Dynamic3CommandExceptionType(
-        (block, property, value) -> Component.translatableEscape("argument.block.property.invalid", block, value, property)
-    );
-    public static final Dynamic2CommandExceptionType ERROR_EXPECTED_VALUE = new Dynamic2CommandExceptionType(
-        (block, property) -> Component.translatableEscape("argument.block.property.novalue", block, property)
-    );
-    public static final SimpleCommandExceptionType ERROR_EXPECTED_END_OF_PROPERTIES = new SimpleCommandExceptionType(
-        Component.translatable("argument.block.property.unclosed")
-    );
-    public static final DynamicCommandExceptionType ERROR_UNKNOWN_TAG = new DynamicCommandExceptionType(
-        tag -> Component.translatableEscape("arguments.block.tag.unknown", tag)
-    );
+
+    public static final SimpleCommandExceptionType ERROR_NO_TAGS_ALLOWED = new SimpleCommandExceptionType(Component.translatable("argument.block.tag.disallowed"));
+    public static final DynamicCommandExceptionType ERROR_UNKNOWN_BLOCK = new DynamicCommandExceptionType((object) -> {
+        return Component.translatableEscape("argument.block.id.invalid", object);
+    });
+    public static final Dynamic2CommandExceptionType ERROR_UNKNOWN_PROPERTY = new Dynamic2CommandExceptionType((object, object1) -> {
+        return Component.translatableEscape("argument.block.property.unknown", object, object1);
+    });
+    public static final Dynamic2CommandExceptionType ERROR_DUPLICATE_PROPERTY = new Dynamic2CommandExceptionType((object, object1) -> {
+        return Component.translatableEscape("argument.block.property.duplicate", object1, object);
+    });
+    public static final Dynamic3CommandExceptionType ERROR_INVALID_VALUE = new Dynamic3CommandExceptionType((object, object1, object2) -> {
+        return Component.translatableEscape("argument.block.property.invalid", object, object2, object1);
+    });
+    public static final Dynamic2CommandExceptionType ERROR_EXPECTED_VALUE = new Dynamic2CommandExceptionType((object, object1) -> {
+        return Component.translatableEscape("argument.block.property.novalue", object, object1);
+    });
+    public static final SimpleCommandExceptionType ERROR_EXPECTED_END_OF_PROPERTIES = new SimpleCommandExceptionType(Component.translatable("argument.block.property.unclosed"));
+    public static final DynamicCommandExceptionType ERROR_UNKNOWN_TAG = new DynamicCommandExceptionType((object) -> {
+        return Component.translatableEscape("arguments.block.tag.unknown", object);
+    });
     private static final char SYNTAX_START_PROPERTIES = '[';
     private static final char SYNTAX_START_NBT = '{';
     private static final char SYNTAX_END_PROPERTIES = ']';
@@ -69,7 +67,7 @@
     private final StringReader reader;
     private final boolean forTesting;
     private final boolean allowNbt;
-    private final Map<Property<?>, Comparable<?>> properties = Maps.newHashMap();
+    private final Map<Property<?>, Comparable<?>> properties = Maps.newLinkedHashMap(); // CraftBukkit - stable
     private final Map<String, String> vagueProperties = Maps.newHashMap();
     private ResourceLocation id = new ResourceLocation("");
     @Nullable
@@ -80,9 +78,10 @@
     private CompoundTag nbt;
     @Nullable
     private HolderSet<Block> tag;
-    private Function<SuggestionsBuilder, CompletableFuture<Suggestions>> suggestions = SUGGEST_NOTHING;
+    private Function<SuggestionsBuilder, CompletableFuture<Suggestions>> suggestions;
 
     private BlockStateParser(HolderLookup<Block> registryWrapper, StringReader reader, boolean allowTag, boolean allowSnbt) {
+        this.suggestions = BlockStateParser.SUGGEST_NOTHING;
         this.blocks = registryWrapper;
         this.reader = reader;
         this.forTesting = allowTag;
@@ -90,58 +89,54 @@
     }
 
     public static BlockStateParser.BlockResult parseForBlock(HolderLookup<Block> registryWrapper, String string, boolean allowSnbt) throws CommandSyntaxException {
-        return parseForBlock(registryWrapper, new StringReader(string), allowSnbt);
+        return BlockStateParser.parseForBlock(registryWrapper, new StringReader(string), allowSnbt);
     }
 
     public static BlockStateParser.BlockResult parseForBlock(HolderLookup<Block> registryWrapper, StringReader reader, boolean allowSnbt) throws CommandSyntaxException {
         int i = reader.getCursor();
 
         try {
-            BlockStateParser blockStateParser = new BlockStateParser(registryWrapper, reader, false, allowSnbt);
-            blockStateParser.parse();
-            return new BlockStateParser.BlockResult(blockStateParser.state, blockStateParser.properties, blockStateParser.nbt);
-        } catch (CommandSyntaxException var5) {
+            BlockStateParser argumentblock = new BlockStateParser(registryWrapper, reader, false, allowSnbt);
+
+            argumentblock.parse();
+            return new BlockStateParser.BlockResult(argumentblock.state, argumentblock.properties, argumentblock.nbt);
+        } catch (CommandSyntaxException commandsyntaxexception) {
             reader.setCursor(i);
-            throw var5;
+            throw commandsyntaxexception;
         }
     }
 
-    public static Either<BlockStateParser.BlockResult, BlockStateParser.TagResult> parseForTesting(
-        HolderLookup<Block> registryWrapper, String string, boolean allowSnbt
-    ) throws CommandSyntaxException {
-        return parseForTesting(registryWrapper, new StringReader(string), allowSnbt);
+    public static Either<BlockStateParser.BlockResult, BlockStateParser.TagResult> parseForTesting(HolderLookup<Block> registryWrapper, String string, boolean allowSnbt) throws CommandSyntaxException {
+        return BlockStateParser.parseForTesting(registryWrapper, new StringReader(string), allowSnbt);
     }
 
-    public static Either<BlockStateParser.BlockResult, BlockStateParser.TagResult> parseForTesting(
-        HolderLookup<Block> registryWrapper, StringReader reader, boolean allowSnbt
-    ) throws CommandSyntaxException {
+    public static Either<BlockStateParser.BlockResult, BlockStateParser.TagResult> parseForTesting(HolderLookup<Block> registryWrapper, StringReader reader, boolean allowSnbt) throws CommandSyntaxException {
         int i = reader.getCursor();
 
         try {
-            BlockStateParser blockStateParser = new BlockStateParser(registryWrapper, reader, true, allowSnbt);
-            blockStateParser.parse();
-            return blockStateParser.tag != null
-                ? Either.right(new BlockStateParser.TagResult(blockStateParser.tag, blockStateParser.vagueProperties, blockStateParser.nbt))
-                : Either.left(new BlockStateParser.BlockResult(blockStateParser.state, blockStateParser.properties, blockStateParser.nbt));
-        } catch (CommandSyntaxException var5) {
+            BlockStateParser argumentblock = new BlockStateParser(registryWrapper, reader, true, allowSnbt);
+
+            argumentblock.parse();
+            return argumentblock.tag != null ? Either.right(new BlockStateParser.TagResult(argumentblock.tag, argumentblock.vagueProperties, argumentblock.nbt)) : Either.left(new BlockStateParser.BlockResult(argumentblock.state, argumentblock.properties, argumentblock.nbt));
+        } catch (CommandSyntaxException commandsyntaxexception) {
             reader.setCursor(i);
-            throw var5;
+            throw commandsyntaxexception;
         }
     }
 
-    public static CompletableFuture<Suggestions> fillSuggestions(
-        HolderLookup<Block> registryWrapper, SuggestionsBuilder builder, boolean allowTag, boolean allowSnbt
-    ) {
-        StringReader stringReader = new StringReader(builder.getInput());
-        stringReader.setCursor(builder.getStart());
-        BlockStateParser blockStateParser = new BlockStateParser(registryWrapper, stringReader, allowTag, allowSnbt);
+    public static CompletableFuture<Suggestions> fillSuggestions(HolderLookup<Block> registryWrapper, SuggestionsBuilder builder, boolean allowTag, boolean allowSnbt) {
+        StringReader stringreader = new StringReader(builder.getInput());
+
+        stringreader.setCursor(builder.getStart());
+        BlockStateParser argumentblock = new BlockStateParser(registryWrapper, stringreader, allowTag, allowSnbt);
 
         try {
-            blockStateParser.parse();
-        } catch (CommandSyntaxException var7) {
+            argumentblock.parse();
+        } catch (CommandSyntaxException commandsyntaxexception) {
+            ;
         }
 
-        return blockStateParser.suggestions.apply(builder.createOffset(stringReader.getCursor()));
+        return (CompletableFuture) argumentblock.suggestions.apply(builder.createOffset(stringreader.getCursor()));
     }
 
     private void parse() throws CommandSyntaxException {
@@ -168,9 +163,10 @@
         }
 
         if (this.allowNbt && this.reader.canRead() && this.reader.peek() == '{') {
-            this.suggestions = SUGGEST_NOTHING;
+            this.suggestions = BlockStateParser.SUGGEST_NOTHING;
             this.readNbt();
         }
+
     }
 
     private CompletableFuture<Suggestions> suggestPropertyNameOrEnd(SuggestionsBuilder builder) {
@@ -190,11 +186,14 @@
     }
 
     private CompletableFuture<Suggestions> suggestPropertyName(SuggestionsBuilder builder) {
-        String string = builder.getRemaining().toLowerCase(Locale.ROOT);
+        String s = builder.getRemaining().toLowerCase(Locale.ROOT);
+        Iterator iterator = this.state.getProperties().iterator();
 
-        for (Property<?> property : this.state.getProperties()) {
-            if (!this.properties.containsKey(property) && property.getName().startsWith(string)) {
-                builder.suggest(property.getName() + "=");
+        while (iterator.hasNext()) {
+            Property<?> iblockstate = (Property) iterator.next();
+
+            if (!this.properties.containsKey(iblockstate) && iblockstate.getName().startsWith(s)) {
+                builder.suggest(iblockstate.getName() + "=");
             }
         }
 
@@ -202,12 +201,20 @@
     }
 
     private CompletableFuture<Suggestions> suggestVaguePropertyName(SuggestionsBuilder builder) {
-        String string = builder.getRemaining().toLowerCase(Locale.ROOT);
+        String s = builder.getRemaining().toLowerCase(Locale.ROOT);
+
         if (this.tag != null) {
-            for (Holder<Block> holder : this.tag) {
-                for (Property<?> property : holder.value().getStateDefinition().getProperties()) {
-                    if (!this.vagueProperties.containsKey(property.getName()) && property.getName().startsWith(string)) {
-                        builder.suggest(property.getName() + "=");
+            Iterator iterator = this.tag.iterator();
+
+            while (iterator.hasNext()) {
+                Holder<Block> holder = (Holder) iterator.next();
+                Iterator iterator1 = ((Block) holder.value()).getStateDefinition().getProperties().iterator();
+
+                while (iterator1.hasNext()) {
+                    Property<?> iblockstate = (Property) iterator1.next();
+
+                    if (!this.vagueProperties.containsKey(iblockstate.getName()) && iblockstate.getName().startsWith(s)) {
+                        builder.suggest(iblockstate.getName() + "=");
                     }
                 }
             }
@@ -229,8 +236,12 @@
             return this.state.hasBlockEntity();
         } else {
             if (this.tag != null) {
-                for (Holder<Block> holder : this.tag) {
-                    if (holder.value().defaultBlockState().hasBlockEntity()) {
+                Iterator iterator = this.tag.iterator();
+
+                while (iterator.hasNext()) {
+                    Holder<Block> holder = (Holder) iterator.next();
+
+                    if (((Block) holder.value()).defaultBlockState().hasBlockEntity()) {
                         return true;
                     }
                 }
@@ -261,11 +272,15 @@
     }
 
     private static <T extends Comparable<T>> SuggestionsBuilder addSuggestions(SuggestionsBuilder builder, Property<T> property) {
-        for (T comparable : property.getPossibleValues()) {
-            if (comparable instanceof Integer integer) {
+        Iterator iterator = property.getPossibleValues().iterator();
+
+        while (iterator.hasNext()) {
+            T t0 = (T) iterator.next(); // CraftBukkit - decompile error
+
+            if (t0 instanceof Integer integer) {
                 builder.suggest(integer);
             } else {
-                builder.suggest(property.getName(comparable));
+                builder.suggest(property.getName(t0));
             }
         }
 
@@ -273,19 +288,28 @@
     }
 
     private CompletableFuture<Suggestions> suggestVaguePropertyValue(SuggestionsBuilder builder, String name) {
-        boolean bl = false;
+        boolean flag = false;
+
         if (this.tag != null) {
-            for (Holder<Block> holder : this.tag) {
-                Block block = holder.value();
-                Property<?> property = block.getStateDefinition().getProperty(name);
-                if (property != null) {
-                    addSuggestions(builder, property);
+            Iterator iterator = this.tag.iterator();
+
+            while (iterator.hasNext()) {
+                Holder<Block> holder = (Holder) iterator.next();
+                Block block = (Block) holder.value();
+                Property<?> iblockstate = block.getStateDefinition().getProperty(name);
+
+                if (iblockstate != null) {
+                    BlockStateParser.addSuggestions(builder, iblockstate);
                 }
 
-                if (!bl) {
-                    for (Property<?> property2 : block.getStateDefinition().getProperties()) {
-                        if (!this.vagueProperties.containsKey(property2.getName())) {
-                            bl = true;
+                if (!flag) {
+                    Iterator iterator1 = block.getStateDefinition().getProperties().iterator();
+
+                    while (iterator1.hasNext()) {
+                        Property<?> iblockstate1 = (Property) iterator1.next();
+
+                        if (!this.vagueProperties.containsKey(iblockstate1.getName())) {
+                            flag = true;
                             break;
                         }
                     }
@@ -293,7 +317,7 @@
             }
         }
 
-        if (bl) {
+        if (flag) {
             builder.suggest(String.valueOf(','));
         }
 
@@ -303,23 +327,26 @@
 
     private CompletableFuture<Suggestions> suggestOpenVaguePropertiesOrNbt(SuggestionsBuilder builder) {
         if (builder.getRemaining().isEmpty() && this.tag != null) {
-            boolean bl = false;
-            boolean bl2 = false;
+            boolean flag = false;
+            boolean flag1 = false;
+            Iterator iterator = this.tag.iterator();
 
-            for (Holder<Block> holder : this.tag) {
-                Block block = holder.value();
-                bl |= !block.getStateDefinition().getProperties().isEmpty();
-                bl2 |= block.defaultBlockState().hasBlockEntity();
-                if (bl && bl2) {
+            while (iterator.hasNext()) {
+                Holder<Block> holder = (Holder) iterator.next();
+                Block block = (Block) holder.value();
+
+                flag |= !block.getStateDefinition().getProperties().isEmpty();
+                flag1 |= block.defaultBlockState().hasBlockEntity();
+                if (flag && flag1) {
                     break;
                 }
             }
 
-            if (bl) {
+            if (flag) {
                 builder.suggest(String.valueOf('['));
             }
 
-            if (bl2) {
+            if (flag1) {
                 builder.suggest(String.valueOf('{'));
             }
         }
@@ -357,26 +384,30 @@
 
     private void readBlock() throws CommandSyntaxException {
         int i = this.reader.getCursor();
+
         this.id = ResourceLocation.read(this.reader);
-        Block block = this.blocks.get(ResourceKey.create(Registries.BLOCK, this.id)).orElseThrow(() -> {
+        Block block = (Block) ((Holder.Reference) this.blocks.get(ResourceKey.create(Registries.BLOCK, this.id)).orElseThrow(() -> {
             this.reader.setCursor(i);
-            return ERROR_UNKNOWN_BLOCK.createWithContext(this.reader, this.id.toString());
-        }).value();
+            return BlockStateParser.ERROR_UNKNOWN_BLOCK.createWithContext(this.reader, this.id.toString());
+        })).value();
+
         this.definition = block.getStateDefinition();
         this.state = block.defaultBlockState();
     }
 
     private void readTag() throws CommandSyntaxException {
         if (!this.forTesting) {
-            throw ERROR_NO_TAGS_ALLOWED.createWithContext(this.reader);
+            throw BlockStateParser.ERROR_NO_TAGS_ALLOWED.createWithContext(this.reader);
         } else {
             int i = this.reader.getCursor();
+
             this.reader.expect('#');
             this.suggestions = this::suggestTag;
-            ResourceLocation resourceLocation = ResourceLocation.read(this.reader);
-            this.tag = this.blocks.get(TagKey.create(Registries.BLOCK, resourceLocation)).orElseThrow(() -> {
+            ResourceLocation minecraftkey = ResourceLocation.read(this.reader);
+
+            this.tag = (HolderSet) this.blocks.get(TagKey.create(Registries.BLOCK, minecraftkey)).orElseThrow(() -> {
                 this.reader.setCursor(i);
-                return ERROR_UNKNOWN_TAG.createWithContext(this.reader, resourceLocation.toString());
+                return BlockStateParser.ERROR_UNKNOWN_TAG.createWithContext(this.reader, minecraftkey.toString());
             });
         }
     }
@@ -386,51 +417,60 @@
         this.suggestions = this::suggestPropertyNameOrEnd;
         this.reader.skipWhitespace();
 
-        while (this.reader.canRead() && this.reader.peek() != ']') {
-            this.reader.skipWhitespace();
-            int i = this.reader.getCursor();
-            String string = this.reader.readString();
-            Property<?> property = this.definition.getProperty(string);
-            if (property == null) {
-                this.reader.setCursor(i);
-                throw ERROR_UNKNOWN_PROPERTY.createWithContext(this.reader, this.id.toString(), string);
-            }
+        while (true) {
+            if (this.reader.canRead() && this.reader.peek() != ']') {
+                this.reader.skipWhitespace();
+                int i = this.reader.getCursor();
+                String s = this.reader.readString();
+                Property<?> iblockstate = this.definition.getProperty(s);
 
-            if (this.properties.containsKey(property)) {
-                this.reader.setCursor(i);
-                throw ERROR_DUPLICATE_PROPERTY.createWithContext(this.reader, this.id.toString(), string);
-            }
+                if (iblockstate == null) {
+                    this.reader.setCursor(i);
+                    throw BlockStateParser.ERROR_UNKNOWN_PROPERTY.createWithContext(this.reader, this.id.toString(), s);
+                }
 
-            this.reader.skipWhitespace();
-            this.suggestions = this::suggestEquals;
-            if (!this.reader.canRead() || this.reader.peek() != '=') {
-                throw ERROR_EXPECTED_VALUE.createWithContext(this.reader, this.id.toString(), string);
-            }
+                if (this.properties.containsKey(iblockstate)) {
+                    this.reader.setCursor(i);
+                    throw BlockStateParser.ERROR_DUPLICATE_PROPERTY.createWithContext(this.reader, this.id.toString(), s);
+                }
 
-            this.reader.skip();
-            this.reader.skipWhitespace();
-            this.suggestions = builder -> addSuggestions(builder, property).buildFuture();
-            int j = this.reader.getCursor();
-            this.setValue(property, this.reader.readString(), j);
-            this.suggestions = this::suggestNextPropertyOrEnd;
-            this.reader.skipWhitespace();
-            if (this.reader.canRead()) {
-                if (this.reader.peek() != ',') {
-                    if (this.reader.peek() != ']') {
-                        throw ERROR_EXPECTED_END_OF_PROPERTIES.createWithContext(this.reader);
-                    }
-                    break;
+                this.reader.skipWhitespace();
+                this.suggestions = this::suggestEquals;
+                if (!this.reader.canRead() || this.reader.peek() != '=') {
+                    throw BlockStateParser.ERROR_EXPECTED_VALUE.createWithContext(this.reader, this.id.toString(), s);
                 }
 
                 this.reader.skip();
-                this.suggestions = this::suggestPropertyName;
+                this.reader.skipWhitespace();
+                this.suggestions = (suggestionsbuilder) -> {
+                    return BlockStateParser.addSuggestions(suggestionsbuilder, iblockstate).buildFuture();
+                };
+                int j = this.reader.getCursor();
+
+                this.setValue(iblockstate, this.reader.readString(), j);
+                this.suggestions = this::suggestNextPropertyOrEnd;
+                this.reader.skipWhitespace();
+                if (!this.reader.canRead()) {
+                    continue;
+                }
+
+                if (this.reader.peek() == ',') {
+                    this.reader.skip();
+                    this.suggestions = this::suggestPropertyName;
+                    continue;
+                }
+
+                if (this.reader.peek() != ']') {
+                    throw BlockStateParser.ERROR_EXPECTED_END_OF_PROPERTIES.createWithContext(this.reader);
+                }
             }
-        }
 
-        if (this.reader.canRead()) {
-            this.reader.skip();
-        } else {
-            throw ERROR_EXPECTED_END_OF_PROPERTIES.createWithContext(this.reader);
+            if (this.reader.canRead()) {
+                this.reader.skip();
+                return;
+            }
+
+            throw BlockStateParser.ERROR_EXPECTED_END_OF_PROPERTIES.createWithContext(this.reader);
         }
     }
 
@@ -438,100 +478,117 @@
         this.reader.skip();
         this.suggestions = this::suggestVaguePropertyNameOrEnd;
         int i = -1;
+
         this.reader.skipWhitespace();
 
-        while (this.reader.canRead() && this.reader.peek() != ']') {
-            this.reader.skipWhitespace();
-            int j = this.reader.getCursor();
-            String string = this.reader.readString();
-            if (this.vagueProperties.containsKey(string)) {
-                this.reader.setCursor(j);
-                throw ERROR_DUPLICATE_PROPERTY.createWithContext(this.reader, this.id.toString(), string);
-            }
+        while (true) {
+            if (this.reader.canRead() && this.reader.peek() != ']') {
+                this.reader.skipWhitespace();
+                int j = this.reader.getCursor();
+                String s = this.reader.readString();
 
-            this.reader.skipWhitespace();
-            if (!this.reader.canRead() || this.reader.peek() != '=') {
-                this.reader.setCursor(j);
-                throw ERROR_EXPECTED_VALUE.createWithContext(this.reader, this.id.toString(), string);
-            }
+                if (this.vagueProperties.containsKey(s)) {
+                    this.reader.setCursor(j);
+                    throw BlockStateParser.ERROR_DUPLICATE_PROPERTY.createWithContext(this.reader, this.id.toString(), s);
+                }
+
+                this.reader.skipWhitespace();
+                if (!this.reader.canRead() || this.reader.peek() != '=') {
+                    this.reader.setCursor(j);
+                    throw BlockStateParser.ERROR_EXPECTED_VALUE.createWithContext(this.reader, this.id.toString(), s);
+                }
+
+                this.reader.skip();
+                this.reader.skipWhitespace();
+                this.suggestions = (suggestionsbuilder) -> {
+                    return this.suggestVaguePropertyValue(suggestionsbuilder, s);
+                };
+                i = this.reader.getCursor();
+                String s1 = this.reader.readString();
+
+                this.vagueProperties.put(s, s1);
+                this.reader.skipWhitespace();
+                if (!this.reader.canRead()) {
+                    continue;
+                }
 
-            this.reader.skip();
-            this.reader.skipWhitespace();
-            this.suggestions = builder -> this.suggestVaguePropertyValue(builder, string);
-            i = this.reader.getCursor();
-            String string2 = this.reader.readString();
-            this.vagueProperties.put(string, string2);
-            this.reader.skipWhitespace();
-            if (this.reader.canRead()) {
                 i = -1;
-                if (this.reader.peek() != ',') {
-                    if (this.reader.peek() != ']') {
-                        throw ERROR_EXPECTED_END_OF_PROPERTIES.createWithContext(this.reader);
-                    }
-                    break;
+                if (this.reader.peek() == ',') {
+                    this.reader.skip();
+                    this.suggestions = this::suggestVaguePropertyName;
+                    continue;
                 }
 
+                if (this.reader.peek() != ']') {
+                    throw BlockStateParser.ERROR_EXPECTED_END_OF_PROPERTIES.createWithContext(this.reader);
+                }
+            }
+
+            if (this.reader.canRead()) {
                 this.reader.skip();
-                this.suggestions = this::suggestVaguePropertyName;
+                return;
             }
-        }
 
-        if (this.reader.canRead()) {
-            this.reader.skip();
-        } else {
             if (i >= 0) {
                 this.reader.setCursor(i);
             }
 
-            throw ERROR_EXPECTED_END_OF_PROPERTIES.createWithContext(this.reader);
+            throw BlockStateParser.ERROR_EXPECTED_END_OF_PROPERTIES.createWithContext(this.reader);
         }
     }
 
     private void readNbt() throws CommandSyntaxException {
-        this.nbt = new TagParser(this.reader).readStruct();
+        this.nbt = (new TagParser(this.reader)).readStruct();
     }
 
     private <T extends Comparable<T>> void setValue(Property<T> property, String value, int cursor) throws CommandSyntaxException {
         Optional<T> optional = property.getValue(value);
+
         if (optional.isPresent()) {
-            this.state = this.state.setValue(property, optional.get());
-            this.properties.put(property, optional.get());
+            this.state = (BlockState) this.state.setValue(property, (T) optional.get()); // CraftBukkit - decompile error
+            this.properties.put(property, (Comparable) optional.get());
         } else {
             this.reader.setCursor(cursor);
-            throw ERROR_INVALID_VALUE.createWithContext(this.reader, this.id.toString(), property.getName(), value);
+            throw BlockStateParser.ERROR_INVALID_VALUE.createWithContext(this.reader, this.id.toString(), property.getName(), value);
         }
     }
 
     public static String serialize(BlockState state) {
-        StringBuilder stringBuilder = new StringBuilder(state.getBlockHolder().unwrapKey().map(key -> key.location().toString()).orElse("air"));
+        StringBuilder stringbuilder = new StringBuilder((String) state.getBlockHolder().unwrapKey().map((resourcekey) -> {
+            return resourcekey.location().toString();
+        }).orElse("air"));
+
         if (!state.getProperties().isEmpty()) {
-            stringBuilder.append('[');
-            boolean bl = false;
+            stringbuilder.append('[');
+            boolean flag = false;
 
-            for (Entry<Property<?>, Comparable<?>> entry : state.getValues().entrySet()) {
-                if (bl) {
-                    stringBuilder.append(',');
+            for (Iterator iterator = state.getValues().entrySet().iterator(); iterator.hasNext(); flag = true) {
+                Entry<Property<?>, Comparable<?>> entry = (Entry) iterator.next();
+
+                if (flag) {
+                    stringbuilder.append(',');
                 }
 
-                appendProperty(stringBuilder, entry.getKey(), entry.getValue());
-                bl = true;
+                BlockStateParser.appendProperty(stringbuilder, (Property) entry.getKey(), (Comparable) entry.getValue());
             }
 
-            stringBuilder.append(']');
+            stringbuilder.append(']');
         }
 
-        return stringBuilder.toString();
+        return stringbuilder.toString();
     }
 
     private static <T extends Comparable<T>> void appendProperty(StringBuilder builder, Property<T> property, Comparable<?> value) {
         builder.append(property.getName());
         builder.append('=');
-        builder.append(property.getName((T)value));
+        builder.append(property.getName((T) value)); // CraftBukkit - decompile error
     }
 
     public static record BlockResult(BlockState blockState, Map<Property<?>, Comparable<?>> properties, @Nullable CompoundTag nbt) {
+
     }
 
     public static record TagResult(HolderSet<Block> tag, Map<String, String> vagueProperties, @Nullable CompoundTag nbt) {
+
     }
 }
