/*
 * This file is part of SpongeAPI, licensed under the MIT License (MIT).
 *
 * Copyright (c) SpongePowered <https://www.spongepowered.org>
 * Copyright (c) contributors
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package org.spongepowered.api.item.inventory;

import org.spongepowered.api.data.manipulator.DataManipulator;
import org.spongepowered.api.data.manipulator.ImmutableDataManipulator;
import org.spongepowered.api.item.ItemType;

/**
 * Represents a builder interface to create an {@link ItemStack}.
 */
public interface ItemStackBuilder {

    /**
     * Sets the {@link ItemType} of the item stack.
     *
     * @param itemType The type of item
     * @return This builder, for chaining
     */
    ItemStackBuilder itemType(ItemType itemType);

    /**
     * Sets the quantity of the item stack.
     *
     * @param quantity The quantity of the item stack
     * @return This builder, for chaining
     * @throws IllegalArgumentException If the quantity is outside the allowed bounds
     */
    ItemStackBuilder quantity(int quantity) throws IllegalArgumentException;

    /**
     * Sets the {@link DataManipulator} to add to the {@link ItemStack}.
     *
     * @param itemData The item data to set
     * @return This builder, for chaining
     * @throws IllegalArgumentException If the item data is incompatible with the item
     */
    ItemStackBuilder itemData(DataManipulator<?, ?> itemData) throws IllegalArgumentException;

    /**
     * Sets the {@link ImmutableDataManipulator} to add to the
     * {@link ItemStack}.
     *
     * @param itemData The item data to set
     * @return This builder, for chaining
     * @throws IllegalArgumentException If the item data is incompatible
     */
    ItemStackBuilder itemData(ImmutableDataManipulator<?, ?> itemData) throws IllegalArgumentException;

    /**
     * Sets all the settings in this builder from the item stack blueprint.
     *
     * @param itemStack The item stack to copy
     * @return This builder, for chaining
     */
    ItemStackBuilder fromItemStack(ItemStack itemStack);

    /**
     * Resets all information regarding the item stack to be created.
     *
     * @return This builder, for chaining
     */
    ItemStackBuilder reset();

    /**
     * Builds an instance of an ItemStack.
     *
     * @return A new instance of an ItemStack
     * @throws IllegalStateException If the item stack is not completed
     */
    ItemStack build() throws IllegalStateException;

}

@@ -1291,16 +1291,442 @@
 ntory;%0A%0A
+import static com.google.common.base.Preconditions.checkArgument;%0Aimport static com.google.common.base.Preconditions.checkNotNull;%0A%0Aimport org.spongepowered.api.block.BlockSnapshot;%0Aimport org.spongepowered.api.block.BlockState;%0Aimport org.spongepowered.api.block.BlockType;%0Aimport org.spongepowered.api.block.tileentity.TileEntity;%0Aimport org.spongepowered.api.data.DataContainer;%0Aimport org.spongepowered.api.data.DataView;%0A
 import o
@@ -3526,24 +3526,1678 @@
 temStack);%0A%0A
+    /**%0A     * Sets the data to recreate a %7B@link BlockState%7D in a held %7B@link ItemStack%7D%0A     * state.%0A     *%0A     * @param blockState The block state to use%0A     * @return This builder, for chaining%0A     */%0A    default ItemStackBuilder fromBlockState(BlockState blockState) %7B%0A        checkNotNull(blockState);%0A        final BlockType blockType= blockState.getType();%0A        checkArgument(blockType.getItem().isPresent(), %22Missing valid ItemType for BlockType: %22 + blockType.getId());%0A        itemType(blockType.getItem().get());%0A        blockState.getContainers().forEach(this::itemData);%0A        return this;%0A    %7D%0A%0A    /**%0A     * Attempts to reconstruct the builder with all of the data from%0A     * %7B@link ItemStack#toContainer()%7D including all custom data.%0A     *%0A     * @param container The container to deserialize%0A     * @return This bulder, for chaining%0A     */%0A    ItemStackBuilder fromContainer(DataView container);%0A%0A    /**%0A     * Reconstructs this builder to use the %7B@link ItemStackSnapshot%7D%0A     * for all the values and data it may contain.%0A     *%0A     * @param snapshot The snapshot%0A     * @return This builder, for chaining%0A     */%0A    default ItemStackBuilder fromSnapshot(ItemStackSnapshot snapshot) %7B%0A        return fromItemStack(snapshot.createStack());%0A    %7D%0A%0A    /**%0A     * Attempts to reconstruct a %7B@link BlockSnapshot%7D including all data%0A     * and %7B@link TileEntity%7D related data if necessary for creating an%0A     * %7B@link ItemStack%7D representation.%0A     *%0A     * @param blockSnapshot The snapshot to use%0A     * @return This builder, for chaining%0A     */%0A    ItemStackBuilder fromBlockSnapshot(BlockSnapshot blockSnapshot);%0A%0A
     /**%0A    

Enhance usability of ItemStackBuilder.