package ru.dbotthepony.mc.otm.matter

import com.mojang.datafixers.util.Either
import net.minecraft.data.CachedOutput
import net.minecraft.data.DataProvider
import net.minecraft.data.PackOutput
import net.minecraft.resources.ResourceLocation
import net.minecraft.tags.TagKey
import net.minecraft.world.item.Item
import net.minecraft.world.level.ItemLike
import net.minecraftforge.data.event.GatherDataEvent
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.util.WriteOnce
import ru.dbotthepony.mc.otm.core.registryName
import ru.dbotthepony.mc.otm.core.toJsonStrict
import java.util.*
import java.util.concurrent.CompletableFuture
import java.util.function.Consumer
import kotlin.ConcurrentModificationException
import kotlin.collections.ArrayList
import kotlin.collections.LinkedHashMap

@Suppress("FunctionName", "unused")
open class MatterDataProvider(val modid: String? = null) : DataProvider {
	var pathProvider: PackOutput.PathProvider by WriteOnce("You need to call bindPackOutput before registering this data provider")
		private set

	constructor(output: PackOutput, modid: String? = null) : this(modid) {
		bindPackOutput(output)
	}

	constructor(event: GatherDataEvent) : this(event.generator.packOutput, event.modContainer.namespace)

	fun bindPackOutput(output: PackOutput) {
		pathProvider = output.createPathProvider(PackOutput.Target.DATA_PACK, MatterManager.MATTER_DIRECTORY)
	}

	protected val actions = LinkedHashMap<ResourceLocation, AbstractRegistryAction>()

	sealed class Configuration(val name: ResourceLocation) {
		var errorOnFailure: Boolean = false
		var matter: Decimal? = null
		var complexity: Double? = null
		var priority: Int? = null

		var target: Either<ResourceLocation, TagKey<Item>>? = null

		protected fun target(): Either<ResourceLocation, TagKey<Item>> {
			return checkNotNull(target) { "You must define either key or tag for $name" }
		}

		protected fun checkMatterValues() {
			check(matter == null || (matter ?: throw ConcurrentModificationException()) >= Decimal.ZERO) { "Invalid matter value: ${matter ?: throw ConcurrentModificationException()}" }
			check(complexity == null || (complexity ?: throw ConcurrentModificationException()) >= 0.0) { "Invalid matter value: ${matter ?: throw ConcurrentModificationException()}" }
		}

		abstract fun build(): AbstractRegistryAction
	}

	class InsertConfiguration(name: ResourceLocation) : Configuration(name) {
		var replaceIfExists: Boolean = false

		override fun build(): InsertAction {
			checkMatterValues()
			check(matter != null && complexity != null) { "You must define both matter value and complexity for $name" }

			return InsertAction(
				id = target(),
				matter = matter!!,
				complexity = complexity!!,
				priority = Optional.ofNullable(priority),
				errorOnFailure = errorOnFailure,
				replaceIfExists = replaceIfExists,
			)
		}
	}

	class DeleteConfiguration(name: ResourceLocation) : Configuration(name) {
		override fun build(): DeleteAction {
			check(matter == null) { "Delete action can't have matter value" }
			check(complexity == null) { "Delete action can't have complexity value" }

			return DeleteAction(target(), errorOnFailure = errorOnFailure)
		}
	}

	class BlacklistConfiguration(name: ResourceLocation) : Configuration(name) {
		override fun build(): BlacklistAction {
			check(matter == null) { "Blacklist action can't have matter value" }
			check(complexity == null) { "Blacklist action can't have complexity value" }
			check(!errorOnFailure) { "Blacklist can't error on 'failure'" }

			return BlacklistAction(target())
		}
	}

	class ComputeConfiguration(name: ResourceLocation) : Configuration(name) {
		val values = ArrayList<ComputeAction.Source>()

		fun add(value: ComputeAction.Source): ComputeConfiguration {
			values.add(value)
			return this
		}

		fun plus(matter: Decimal, complexity: Double): ComputeConfiguration {
			values.add(ComputeAction.Constant(matter, complexity, IMatterFunction.PLUS))
			return this
		}

		fun minus(matter: Decimal, complexity: Double): ComputeConfiguration {
			values.add(ComputeAction.Constant(matter, complexity, IMatterFunction.MINUS))
			return this
		}

		fun multiply(matter: Decimal, complexity: Double): ComputeConfiguration {
			values.add(ComputeAction.Constant(matter, complexity, IMatterFunction.MUL))
			return this
		}

		fun divide(matter: Decimal, complexity: Double): ComputeConfiguration {
			values.add(ComputeAction.Constant(matter, complexity, IMatterFunction.DIV))
			return this
		}

		fun plus(key: ResourceLocation): ComputeConfiguration {
			values.add(ComputeAction.Value(Either.left(key), IMatterFunction.PLUS))
			return this
		}

		fun plus(key: ItemLike): ComputeConfiguration {
			values.add(ComputeAction.Value(Either.left(key.asItem().registryName!!), IMatterFunction.PLUS))
			return this
		}

		fun minus(key: ResourceLocation): ComputeConfiguration {
			values.add(ComputeAction.Value(Either.left(key), IMatterFunction.MINUS))
			return this
		}

		fun minus(key: ItemLike): ComputeConfiguration {
			values.add(ComputeAction.Value(Either.left(key.asItem().registryName!!), IMatterFunction.MINUS))
			return this
		}

		fun multiply(key: ResourceLocation): ComputeConfiguration {
			values.add(ComputeAction.Value(Either.left(key), IMatterFunction.MUL))
			return this
		}

		fun multiply(key: ItemLike): ComputeConfiguration {
			values.add(ComputeAction.Value(Either.left(key.asItem().registryName!!), IMatterFunction.MUL))
			return this
		}

		fun divide(key: ResourceLocation): ComputeConfiguration {
			values.add(ComputeAction.Value(Either.left(key), IMatterFunction.DIV))
			return this
		}

		fun divide(key: ItemLike): ComputeConfiguration {
			values.add(ComputeAction.Value(Either.left(key.asItem().registryName!!), IMatterFunction.DIV))
			return this
		}

		fun plus(tag: TagKey<Item>): ComputeConfiguration {
			values.add(ComputeAction.Value(Either.right(tag), IMatterFunction.PLUS))
			return this
		}

		fun minus(tag: TagKey<Item>): ComputeConfiguration {
			values.add(ComputeAction.Value(Either.right(tag), IMatterFunction.MINUS))
			return this
		}

		fun multiply(tag: TagKey<Item>): ComputeConfiguration {
			values.add(ComputeAction.Value(Either.right(tag), IMatterFunction.MUL))
			return this
		}

		fun divide(tag: TagKey<Item>): ComputeConfiguration {
			values.add(ComputeAction.Value(Either.right(tag), IMatterFunction.DIV))
			return this
		}

		override fun build(): ComputeAction {
			check(matter == null) { "Compute action can't have matter value" }
			check(complexity == null) { "Compute action can't have complexity value" }
			check(values.isNotEmpty()) { "Compute action is empty" }

			return ComputeAction(target(), values,)
		}
	}

	class UpdateConfiguration(name: ResourceLocation) : Configuration(name) {
		val matterFunctions = ArrayList<UpdateAction.MatterFunction>()
		val complexityFunctions = ArrayList<UpdateAction.ComplexityFunction>()
		val priorityFunctions = ArrayList<UpdateAction.PriorityFunction>()

		fun addMatterFunction(function: IMatterFunction, value: Decimal): UpdateConfiguration {
			matterFunctions.add(UpdateAction.MatterFunction(function, value))
			return this
		}

		fun addComplexityFunction(function: IMatterFunction, value: Double): UpdateConfiguration {
			complexityFunctions.add(UpdateAction.ComplexityFunction(function, value))
			return this
		}

		fun addPriorityFunction(function: IMatterFunction, value: Int): UpdateConfiguration {
			priorityFunctions.add(UpdateAction.PriorityFunction(function, value))
			return this
		}

		override fun build(): UpdateAction {
			check(
				matterFunctions.isNotEmpty() ||
				complexityFunctions.isNotEmpty() ||
				priorityFunctions.isNotEmpty()
			) { "Update configuration is completely empty" }

			return UpdateAction(
				target(),
				errorOnFailure = errorOnFailure,
				matterFunctions = matterFunctions,
				complexityFunctions = complexityFunctions,
				priorityFunctions = priorityFunctions
			)
		}
	}

	fun Scope(						matterValue: Int, complexity: Double, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity, configurator)
	fun Scope(item: ItemLike, 		matterValue: Int, complexity: Double, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity, configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Double, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity, configurator)
	fun Scope(						matterValue: Long, complexity: Double, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity, configurator)
	fun Scope(item: ItemLike, 		matterValue: Long, complexity: Double, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity, configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Double, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity, configurator)
	fun Scope(						matterValue: Double, complexity: Double, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity, configurator)
	fun Scope(item: ItemLike, 		matterValue: Double, complexity: Double, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity, configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Double, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity, configurator)
	fun Scope(						matterValue: Float, complexity: Double, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity, configurator)
	fun Scope(item: ItemLike, 		matterValue: Float, complexity: Double, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity, configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Double, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity, configurator)

	fun Scope(						matterValue: Int, complexity: Int, 							configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(item: ItemLike, 		matterValue: Int, complexity: Int, 							configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Int, 							configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(						matterValue: Long, complexity: Int, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(item: ItemLike, 		matterValue: Long, complexity: Int, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Int, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(						matterValue: Double, complexity: Int, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(item: ItemLike, 		matterValue: Double, complexity: Int, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Int, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(						matterValue: Float, complexity: Int, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(item: ItemLike, 		matterValue: Float, complexity: Int, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Int, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)

	fun Scope(						matterValue: Int, complexity: Float, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(item: ItemLike, 		matterValue: Int, complexity: Float, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Float, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(						matterValue: Long, complexity: Float, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(item: ItemLike, 		matterValue: Long, complexity: Float, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Float, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(						matterValue: Double, complexity: Float, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(item: ItemLike, 		matterValue: Double, complexity: Float, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Float, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(						matterValue: Float, complexity: Float, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(item: ItemLike, 		matterValue: Float, complexity: Float, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Float, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)

	fun Scope(						matterValue: Int, complexity: Long, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(item: ItemLike, 		matterValue: Int, complexity: Long, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Long, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(						matterValue: Long, complexity: Long, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(item: ItemLike, 		matterValue: Long, complexity: Long, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Long, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(						matterValue: Double, complexity: Long, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(item: ItemLike, 		matterValue: Double, complexity: Long, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Long, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(						matterValue: Float, complexity: Long, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(item: ItemLike, 		matterValue: Float, complexity: Long, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Long, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)

	fun scope(matterValue: Decimal, complexity: Double, configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(matterValue, complexity, configurator)
	fun scope(item: ItemLike, matterValue: Decimal, complexity: Double, configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, matterValue, complexity, configurator)
	fun scope(tag: TagKey<Item>, matterValue: Decimal, complexity: Double, configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, matterValue, complexity, configurator)
	fun scope(						matterValue: Int, complexity: Double, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity, configurator)
	fun scope(item: ItemLike, 		matterValue: Int, complexity: Double, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity, configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Double, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity, configurator)
	fun scope(						matterValue: Long, complexity: Double, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity, configurator)
	fun scope(item: ItemLike, 		matterValue: Long, complexity: Double, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity, configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Double, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity, configurator)
	fun scope(						matterValue: Double, complexity: Double, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity, configurator)
	fun scope(item: ItemLike, 		matterValue: Double, complexity: Double, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity, configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Double, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity, configurator)
	fun scope(						matterValue: Float, complexity: Double, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity, configurator)
	fun scope(item: ItemLike, 		matterValue: Float, complexity: Double, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity, configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Double, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity, configurator)

	fun scope(						matterValue: Int, complexity: Int, 							configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(item: ItemLike, 		matterValue: Int, complexity: Int, 							configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Int, 							configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(						matterValue: Long, complexity: Int, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(item: ItemLike, 		matterValue: Long, complexity: Int, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Int, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(						matterValue: Double, complexity: Int, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(item: ItemLike, 		matterValue: Double, complexity: Int, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Int, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(						matterValue: Float, complexity: Int, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(item: ItemLike, 		matterValue: Float, complexity: Int, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Int, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)

	fun scope(						matterValue: Int, complexity: Float, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(item: ItemLike, 		matterValue: Int, complexity: Float, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Float, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(						matterValue: Long, complexity: Float, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(item: ItemLike, 		matterValue: Long, complexity: Float, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Float, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(						matterValue: Double, complexity: Float, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(item: ItemLike, 		matterValue: Double, complexity: Float, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Float, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(						matterValue: Float, complexity: Float, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(item: ItemLike, 		matterValue: Float, complexity: Float, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Float, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)

	fun scope(						matterValue: Int, complexity: Long, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(item: ItemLike, 		matterValue: Int, complexity: Long, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Long, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(						matterValue: Long, complexity: Long, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(item: ItemLike, 		matterValue: Long, complexity: Long, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Long, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(						matterValue: Double, complexity: Long, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(item: ItemLike, 		matterValue: Double, complexity: Long, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Long, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(						matterValue: Float, complexity: Long, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(item: ItemLike, 		matterValue: Float, complexity: Long, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Long, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)

	fun Scope(						matterValue: Int, complexity: Double, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity, configurator)
	fun Scope(item: ItemLike, 		matterValue: Int, complexity: Double, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity, configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Double, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity, configurator)
	fun Scope(						matterValue: Long, complexity: Double, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity, configurator)
	fun Scope(item: ItemLike, 		matterValue: Long, complexity: Double, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity, configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Double, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity, configurator)
	fun Scope(						matterValue: Double, complexity: Double, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity, configurator)
	fun Scope(item: ItemLike, 		matterValue: Double, complexity: Double, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity, configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Double, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity, configurator)
	fun Scope(						matterValue: Float, complexity: Double, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity, configurator)
	fun Scope(item: ItemLike, 		matterValue: Float, complexity: Double, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity, configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Double, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity, configurator)

	fun Scope(						matterValue: Int, complexity: Int, 							configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(item: ItemLike, 		matterValue: Int, complexity: Int, 							configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Int, 							configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(						matterValue: Long, complexity: Int, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(item: ItemLike, 		matterValue: Long, complexity: Int, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Int, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(						matterValue: Double, complexity: Int, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(item: ItemLike, 		matterValue: Double, complexity: Int, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Int, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(						matterValue: Float, complexity: Int, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(item: ItemLike, 		matterValue: Float, complexity: Int, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Int, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)

	fun Scope(						matterValue: Int, complexity: Float, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(item: ItemLike, 		matterValue: Int, complexity: Float, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Float, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(						matterValue: Long, complexity: Float, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(item: ItemLike, 		matterValue: Long, complexity: Float, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Float, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(						matterValue: Double, complexity: Float, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(item: ItemLike, 		matterValue: Double, complexity: Float, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Float, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(						matterValue: Float, complexity: Float, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(item: ItemLike, 		matterValue: Float, complexity: Float, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Float, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)

	fun Scope(						matterValue: Int, complexity: Long, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(item: ItemLike, 		matterValue: Int, complexity: Long, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Long, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(						matterValue: Long, complexity: Long, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(item: ItemLike, 		matterValue: Long, complexity: Long, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Long, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(						matterValue: Double, complexity: Long, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(item: ItemLike, 		matterValue: Double, complexity: Long, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Long, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(						matterValue: Float, complexity: Long, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(item: ItemLike, 		matterValue: Float, complexity: Long, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun Scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Long, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)

	fun scope(matterValue: Decimal, complexity: Double, configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(matterValue, complexity, configurator)
	fun scope(item: ItemLike, matterValue: Decimal, complexity: Double, configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, matterValue, complexity, configurator)
	fun scope(tag: TagKey<Item>, matterValue: Decimal, complexity: Double, configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, matterValue, complexity, configurator)
	fun scope(						matterValue: Int, complexity: Double, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity, configurator)
	fun scope(item: ItemLike, 		matterValue: Int, complexity: Double, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity, configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Double, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity, configurator)
	fun scope(						matterValue: Long, complexity: Double, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity, configurator)
	fun scope(item: ItemLike, 		matterValue: Long, complexity: Double, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity, configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Double, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity, configurator)
	fun scope(						matterValue: Double, complexity: Double, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity, configurator)
	fun scope(item: ItemLike, 		matterValue: Double, complexity: Double, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity, configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Double, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity, configurator)
	fun scope(						matterValue: Float, complexity: Double, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity, configurator)
	fun scope(item: ItemLike, 		matterValue: Float, complexity: Double, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity, configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Double, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity, configurator)

	fun scope(						matterValue: Int, complexity: Int, 							configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(item: ItemLike, 		matterValue: Int, complexity: Int, 							configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Int, 							configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(						matterValue: Long, complexity: Int, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(item: ItemLike, 		matterValue: Long, complexity: Int, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Int, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(						matterValue: Double, complexity: Int, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(item: ItemLike, 		matterValue: Double, complexity: Int, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Int, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(						matterValue: Float, complexity: Int, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(item: ItemLike, 		matterValue: Float, complexity: Int, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Int, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)

	fun scope(						matterValue: Int, complexity: Float, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(item: ItemLike, 		matterValue: Int, complexity: Float, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Float, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(						matterValue: Long, complexity: Float, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(item: ItemLike, 		matterValue: Long, complexity: Float, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Float, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(						matterValue: Double, complexity: Float, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(item: ItemLike, 		matterValue: Double, complexity: Float, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Float, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(						matterValue: Float, complexity: Float, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(item: ItemLike, 		matterValue: Float, complexity: Float, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Float, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)

	fun scope(						matterValue: Int, complexity: Long, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(item: ItemLike, 		matterValue: Int, complexity: Long, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Long, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(						matterValue: Long, complexity: Long, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(item: ItemLike, 		matterValue: Long, complexity: Long, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Long, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(						matterValue: Double, complexity: Long, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(item: ItemLike, 		matterValue: Double, complexity: Long, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Long, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(						matterValue: Float, complexity: Long, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
		Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(item: ItemLike, 		matterValue: Float, complexity: Long, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue), complexity.toDouble(), configurator)
	fun scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Long, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue), complexity.toDouble(), configurator)

	/**
	 * Allows to easily declare matter values using relative costs in DSL pattern
	 */
	inner class Scope(val matterValue: Decimal, val complexity: Double, configurator: Scope.() -> Unit) {
		constructor(item: ItemLike, matterValue: Decimal, complexity: Double, configurator: Scope.() -> Unit) : this(matterValue, complexity, configurator) {
			insert(item, matterValue, complexity)
		}

		constructor(tag: TagKey<Item>, matterValue: Decimal, complexity: Double, configurator: Scope.() -> Unit) : this(matterValue, complexity, configurator) {
			insert(tag, matterValue, complexity)
		}

		constructor(item: ItemLike, matterValue: Decimal, complexity: Double, configurator: Consumer<Scope>) : this(matterValue, complexity, configurator::accept) {
			insert(item, matterValue, complexity)
		}

		constructor(tag: TagKey<Item>, matterValue: Decimal, complexity: Double, configurator: Consumer<Scope>) : this(matterValue, complexity, configurator::accept) {
			insert(tag, matterValue, complexity)
		}

		constructor(matterValue: Decimal, complexity: Double, configurator: Consumer<Scope>) : this(matterValue, complexity, configurator::accept)

		init {
			configurator.invoke(this)
		}

		fun Scope(matterValue: Decimal, complexity: Double, configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(matterValue * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, matterValue: Decimal, complexity: Double, configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, matterValue * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, matterValue: Decimal, complexity: Double, configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, matterValue * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(						matterValue: Int, complexity: Double, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Int, complexity: Double, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Double, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(						matterValue: Long, complexity: Double, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Long, complexity: Double, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Double, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(						matterValue: Double, complexity: Double, 				configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Double, complexity: Double, 				configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Double, 				configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(						matterValue: Float, complexity: Double, 				configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Float, complexity: Double, 				configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Double, 				configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)

		fun Scope(						matterValue: Int, complexity: Int, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Int, complexity: Int, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Int, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(						matterValue: Long, complexity: Int, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Long, complexity: Int, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Int, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(						matterValue: Double, complexity: Int, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Double, complexity: Int, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Int, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(						matterValue: Float, complexity: Int, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Float, complexity: Int, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Int, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)

		fun Scope(						matterValue: Int, complexity: Float, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Int, complexity: Float, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Float, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(						matterValue: Long, complexity: Float, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Long, complexity: Float, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Float, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(						matterValue: Double, complexity: Float, 				configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Double, complexity: Float, 				configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Float, 				configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(						matterValue: Float, complexity: Float, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Float, complexity: Float, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Float, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)

		fun Scope(						matterValue: Int, complexity: Long, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Int, complexity: Long, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Long, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(						matterValue: Long, complexity: Long, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Long, complexity: Long, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Long, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(						matterValue: Double, complexity: Long, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Double, complexity: Long, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Long, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(						matterValue: Float, complexity: Long, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Float, complexity: Long, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Long, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)

		fun scope(matterValue: Decimal, complexity: Double, configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(matterValue * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, matterValue: Decimal, complexity: Double, configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, matterValue * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, matterValue: Decimal, complexity: Double, configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, matterValue * this.matterValue, complexity * this.complexity, configurator)
		fun scope(						matterValue: Int, complexity: Double, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Int, complexity: Double, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Double, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(						matterValue: Long, complexity: Double, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Long, complexity: Double, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Double, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(						matterValue: Double, complexity: Double, 				configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Double, complexity: Double, 				configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Double, 				configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(						matterValue: Float, complexity: Double, 				configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Float, complexity: Double, 				configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Double, 				configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)

		fun scope(						matterValue: Int, complexity: Int, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Int, complexity: Int, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Int, 						configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(						matterValue: Long, complexity: Int, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Long, complexity: Int, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Int, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(						matterValue: Double, complexity: Int, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Double, complexity: Int, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Int, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(						matterValue: Float, complexity: Int, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Float, complexity: Int, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Int, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)

		fun scope(						matterValue: Int, complexity: Float, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Int, complexity: Float, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Float, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(						matterValue: Long, complexity: Float, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Long, complexity: Float, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Float, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(						matterValue: Double, complexity: Float, 				configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Double, complexity: Float, 				configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Float, 				configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(						matterValue: Float, complexity: Float, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Float, complexity: Float, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Float, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)

		fun scope(						matterValue: Int, complexity: Long, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Int, complexity: Long, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Long, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(						matterValue: Long, complexity: Long, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Long, complexity: Long, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Long, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(						matterValue: Double, complexity: Long, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Double, complexity: Long, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Long, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(						matterValue: Float, complexity: Long, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Float, complexity: Long, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Long, 					configurator: Scope.() -> Unit) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)

		// ----
		fun Scope(matterValue: Decimal, complexity: Double, configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(matterValue * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, matterValue: Decimal, complexity: Double, configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, matterValue * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, matterValue: Decimal, complexity: Double, configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, matterValue * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(						matterValue: Int, complexity: Double, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Int, complexity: Double, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Double, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(						matterValue: Long, complexity: Double, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Long, complexity: Double, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Double, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(						matterValue: Double, complexity: Double, 				configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Double, complexity: Double, 				configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Double, 				configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(						matterValue: Float, complexity: Double, 				configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Float, complexity: Double, 				configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Double, 				configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)

		fun Scope(						matterValue: Int, complexity: Int, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Int, complexity: Int, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Int, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(						matterValue: Long, complexity: Int, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Long, complexity: Int, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Int, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(						matterValue: Double, complexity: Int, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Double, complexity: Int, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Int, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(						matterValue: Float, complexity: Int, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Float, complexity: Int, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Int, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)

		fun Scope(						matterValue: Int, complexity: Float, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Int, complexity: Float, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Float, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(						matterValue: Long, complexity: Float, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Long, complexity: Float, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Float, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(						matterValue: Double, complexity: Float, 				configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Double, complexity: Float, 				configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Float, 				configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(						matterValue: Float, complexity: Float, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Float, complexity: Float, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Float, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)

		fun Scope(						matterValue: Int, complexity: Long, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Int, complexity: Long, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Long, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(						matterValue: Long, complexity: Long, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Long, complexity: Long, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Long, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(						matterValue: Double, complexity: Long, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Double, complexity: Long, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Long, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(						matterValue: Float, complexity: Long, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(item: ItemLike, 		matterValue: Float, complexity: Long, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun Scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Long, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)

		fun scope(matterValue: Decimal, complexity: Double, configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(matterValue * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, matterValue: Decimal, complexity: Double, configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, matterValue * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, matterValue: Decimal, complexity: Double, configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, matterValue * this.matterValue, complexity * this.complexity, configurator)
		fun scope(						matterValue: Int, complexity: Double, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Int, complexity: Double, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Double, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(						matterValue: Long, complexity: Double, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Long, complexity: Double, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Double, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(						matterValue: Double, complexity: Double, 				configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Double, complexity: Double, 				configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Double, 				configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(						matterValue: Float, complexity: Double, 				configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Float, complexity: Double, 				configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Double, 				configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)

		fun scope(						matterValue: Int, complexity: Int, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Int, complexity: Int, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Int, 						configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(						matterValue: Long, complexity: Int, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Long, complexity: Int, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Int, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(						matterValue: Double, complexity: Int, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Double, complexity: Int, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Int, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(						matterValue: Float, complexity: Int, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Float, complexity: Int, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Int, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)

		fun scope(						matterValue: Int, complexity: Float, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Int, complexity: Float, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Float, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(						matterValue: Long, complexity: Float, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Long, complexity: Float, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Float, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(						matterValue: Double, complexity: Float, 				configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Double, complexity: Float, 				configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Float, 				configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(						matterValue: Float, complexity: Float, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Float, complexity: Float, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Float, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)

		fun scope(						matterValue: Int, complexity: Long, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Int, complexity: Long, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Int, complexity: Long, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(						matterValue: Long, complexity: Long, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Long, complexity: Long, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Long, complexity: Long, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(						matterValue: Double, complexity: Long, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Double, complexity: Long, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Double, complexity: Long, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(						matterValue: Float, complexity: Long, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(
			Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(item: ItemLike, 		matterValue: Float, complexity: Long, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun scope(tag: TagKey<Item>, 	matterValue: Float, complexity: Long, 					configurator: Consumer<Scope>) = this@MatterDataProvider.Scope(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)

		//////////
		fun relative(item: ItemLike, matterValue: Decimal, complexity: Double, configurator: InsertConfiguration.() -> Unit) = insert(item, matterValue * this.matterValue, complexity * this.complexity, configurator)
		fun relative(tag: TagKey<Item>, matterValue: Decimal, complexity: Double, configurator: InsertConfiguration.() -> Unit) = insert(tag, matterValue * this.matterValue, complexity * this.complexity, configurator)
		fun relative(item: ItemLike, 		matterValue: Int, complexity: Double, 				configurator: InsertConfiguration.() -> Unit) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(tag: TagKey<Item>, 	matterValue: Int, complexity: Double, 				configurator: InsertConfiguration.() -> Unit) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(item: ItemLike, 		matterValue: Long, complexity: Double, 				configurator: InsertConfiguration.() -> Unit) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(tag: TagKey<Item>, 	matterValue: Long, complexity: Double, 				configurator: InsertConfiguration.() -> Unit) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(item: ItemLike, 		matterValue: Double, complexity: Double, 			configurator: InsertConfiguration.() -> Unit) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(tag: TagKey<Item>, 	matterValue: Double, complexity: Double, 			configurator: InsertConfiguration.() -> Unit) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(item: ItemLike, 		matterValue: Float, complexity: Double, 			configurator: InsertConfiguration.() -> Unit) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(tag: TagKey<Item>, 	matterValue: Float, complexity: Double, 			configurator: InsertConfiguration.() -> Unit) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)

		fun relative(item: ItemLike, 		matterValue: Int, complexity: Int, 					configurator: InsertConfiguration.() -> Unit) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(tag: TagKey<Item>, 	matterValue: Int, complexity: Int, 					configurator: InsertConfiguration.() -> Unit) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(item: ItemLike, 		matterValue: Long, complexity: Int, 				configurator: InsertConfiguration.() -> Unit) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(tag: TagKey<Item>, 	matterValue: Long, complexity: Int, 				configurator: InsertConfiguration.() -> Unit) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(item: ItemLike, 		matterValue: Double, complexity: Int, 				configurator: InsertConfiguration.() -> Unit) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(tag: TagKey<Item>, 	matterValue: Double, complexity: Int, 				configurator: InsertConfiguration.() -> Unit) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(item: ItemLike, 		matterValue: Float, complexity: Int, 				configurator: InsertConfiguration.() -> Unit) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(tag: TagKey<Item>, 	matterValue: Float, complexity: Int, 				configurator: InsertConfiguration.() -> Unit) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)

		fun relative(item: ItemLike, 		matterValue: Int, complexity: Float, 				configurator: InsertConfiguration.() -> Unit) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(tag: TagKey<Item>, 	matterValue: Int, complexity: Float, 				configurator: InsertConfiguration.() -> Unit) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(item: ItemLike, 		matterValue: Long, complexity: Float, 				configurator: InsertConfiguration.() -> Unit) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(tag: TagKey<Item>, 	matterValue: Long, complexity: Float, 				configurator: InsertConfiguration.() -> Unit) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(item: ItemLike, 		matterValue: Double, complexity: Float, 			configurator: InsertConfiguration.() -> Unit) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(tag: TagKey<Item>, 	matterValue: Double, complexity: Float, 			configurator: InsertConfiguration.() -> Unit) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(item: ItemLike, 		matterValue: Float, complexity: Float, 				configurator: InsertConfiguration.() -> Unit) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(tag: TagKey<Item>, 	matterValue: Float, complexity: Float, 				configurator: InsertConfiguration.() -> Unit) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)

		fun relative(item: ItemLike, 		matterValue: Int, complexity: Long, 				configurator: InsertConfiguration.() -> Unit) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(tag: TagKey<Item>, 	matterValue: Int, complexity: Long, 				configurator: InsertConfiguration.() -> Unit) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(item: ItemLike, 		matterValue: Long, complexity: Long, 				configurator: InsertConfiguration.() -> Unit) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(tag: TagKey<Item>, 	matterValue: Long, complexity: Long, 				configurator: InsertConfiguration.() -> Unit) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(item: ItemLike, 		matterValue: Double, complexity: Long, 				configurator: InsertConfiguration.() -> Unit) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(tag: TagKey<Item>, 	matterValue: Double, complexity: Long, 				configurator: InsertConfiguration.() -> Unit) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(item: ItemLike, 		matterValue: Float, complexity: Long, 				configurator: InsertConfiguration.() -> Unit) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		fun relative(tag: TagKey<Item>, 	matterValue: Float, complexity: Long, 				configurator: InsertConfiguration.() -> Unit) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)

		@JvmOverloads fun relative(item: ItemLike, matterValue: Decimal, complexity: Double, configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(item, matterValue * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(tag: TagKey<Item>, matterValue: Decimal, complexity: Double, configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(tag, matterValue * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(item: ItemLike, 		matterValue: Int, complexity: Double, 				configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(tag: TagKey<Item>, 	matterValue: Int, complexity: Double, 				configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(item: ItemLike, 		matterValue: Long, complexity: Double, 				configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(tag: TagKey<Item>, 	matterValue: Long, complexity: Double, 				configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(item: ItemLike, 		matterValue: Double, complexity: Double, 			configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(tag: TagKey<Item>, 	matterValue: Double, complexity: Double, 			configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(item: ItemLike, 		matterValue: Float, complexity: Double, 			configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(tag: TagKey<Item>, 	matterValue: Float, complexity: Double, 			configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)

		@JvmOverloads fun relative(item: ItemLike, 		matterValue: Int, complexity: Int, 					configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(tag: TagKey<Item>, 	matterValue: Int, complexity: Int, 					configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(item: ItemLike, 		matterValue: Long, complexity: Int, 				configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(tag: TagKey<Item>, 	matterValue: Long, complexity: Int, 				configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(item: ItemLike, 		matterValue: Double, complexity: Int, 				configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(tag: TagKey<Item>, 	matterValue: Double, complexity: Int, 				configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(item: ItemLike, 		matterValue: Float, complexity: Int, 				configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(tag: TagKey<Item>, 	matterValue: Float, complexity: Int, 				configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)

		@JvmOverloads fun relative(item: ItemLike, 		matterValue: Int, complexity: Float, 				configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(tag: TagKey<Item>, 	matterValue: Int, complexity: Float, 				configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(item: ItemLike, 		matterValue: Long, complexity: Float, 				configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(tag: TagKey<Item>, 	matterValue: Long, complexity: Float, 				configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(item: ItemLike, 		matterValue: Double, complexity: Float, 			configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(tag: TagKey<Item>, 	matterValue: Double, complexity: Float, 			configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(item: ItemLike, 		matterValue: Float, complexity: Float, 				configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(tag: TagKey<Item>, 	matterValue: Float, complexity: Float, 				configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)

		@JvmOverloads fun relative(item: ItemLike, 		matterValue: Int, complexity: Long, 				configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(tag: TagKey<Item>, 	matterValue: Int, complexity: Long, 				configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(item: ItemLike, 		matterValue: Long, complexity: Long, 				configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(tag: TagKey<Item>, 	matterValue: Long, complexity: Long, 				configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(item: ItemLike, 		matterValue: Double, complexity: Long, 				configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(tag: TagKey<Item>, 	matterValue: Double, complexity: Long, 				configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(item: ItemLike, 		matterValue: Float, complexity: Long, 				configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(item, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)
		@JvmOverloads fun relative(tag: TagKey<Item>, 	matterValue: Float, complexity: Long, 				configurator: Consumer<InsertConfiguration> = Consumer {}) = insert(tag, Decimal(matterValue) * this.matterValue, complexity * this.complexity, configurator)


		////////
		fun equal(vararg items: ItemLike) {
			for (item in items) {
				insert(item, matterValue, complexity)
			}
		}

		fun equal(item: ItemLike) {
			insert(item, matterValue, complexity)
		}

		fun equal(vararg tags: TagKey<Item>) {
			for (tag in tags) {
				insert(tag, matterValue, complexity)
			}
		}

		fun equal(tag: TagKey<Item>) {
			insert(tag, matterValue, complexity)
		}
	}

	fun insert(name: ResourceLocation, configurator: InsertConfiguration.() -> Unit): InsertAction {
		check(!actions.containsKey(name)) { "Already has action with name $name" }
		val config = InsertConfiguration(name)
		configurator.invoke(config)
		val built = config.build()
		actions[name] = built
		return built
	}

	fun delete(name: ResourceLocation, configurator: DeleteConfiguration.() -> Unit): DeleteAction {
		check(!actions.containsKey(name)) { "Already has action with name $name" }
		val config = DeleteConfiguration(name)
		configurator.invoke(config)
		val built = config.build()
		actions[name] = built
		return built
	}

	fun update(name: ResourceLocation, configurator: UpdateConfiguration.() -> Unit): UpdateAction {
		check(!actions.containsKey(name)) { "Already has action with name $name" }
		val config = UpdateConfiguration(name)
		configurator.invoke(config)
		val built = config.build()
		actions[name] = built
		return built
	}

	fun compute(name: ResourceLocation, configurator: ComputeConfiguration.() -> Unit): ComputeAction {
		check(!actions.containsKey(name)) { "Already has action with name $name" }
		val config = ComputeConfiguration(name)
		configurator.invoke(config)
		val built = config.build()
		actions[name] = built
		return built
	}

	fun blacklist(name: ResourceLocation, configurator: BlacklistConfiguration.() -> Unit): BlacklistAction {
		check(!actions.containsKey(name)) { "Already has action with name $name" }
		val config = BlacklistConfiguration(name)
		configurator.invoke(config)
		val built = config.build()
		actions[name] = built
		return built
	}

	protected fun updateLocation(input: ResourceLocation, prefix: String): ResourceLocation {
		if (modid != null) {
			if (input.namespace == modid) {
				return ResourceLocation(input.namespace, prefix + input.path)
			} else {
				return ResourceLocation(modid, prefix + input.namespace + "/" + input.path)
			}
		} else {
			return ResourceLocation(input.namespace, prefix + input.path)
		}
	}

	protected fun updateLocation(input: ItemLike, prefix: String): ResourceLocation {
		return updateLocation(input.asItem().registryName ?: throw NullPointerException("${input.asItem()} does not have registry name!"), prefix)
	}

	// direct inheritance
	fun inherit(destination: ItemLike, source: ItemLike, configurator: ComputeConfiguration.() -> Unit): ComputeAction {
		return compute(updateLocation(destination, "item/")) {
			target = Either.left(destination.asItem().registryName!!)
			add(ComputeAction.Value(Either.left(source.asItem().registryName!!), IMatterFunction.PLUS))
			configurator.invoke(this)
		}
	}

	fun inherit(destination: TagKey<Item>, source: ItemLike, configurator: ComputeConfiguration.() -> Unit): ComputeAction {
		return compute(updateLocation(destination.location, "tag/")) {
			target = Either.right(destination)
			add(ComputeAction.Value(Either.left(source.asItem().registryName!!), IMatterFunction.PLUS))
			configurator.invoke(this)
		}
	}

	fun inherit(destination: ItemLike, source: TagKey<Item>, configurator: ComputeConfiguration.() -> Unit): ComputeAction {
		return compute(updateLocation(destination, "item/")) {
			target = Either.left(destination.asItem().registryName!!)
			add(ComputeAction.Value(Either.right(source), IMatterFunction.PLUS))
			configurator.invoke(this)
		}
	}

	fun inherit(destination: TagKey<Item>, source: TagKey<Item>, configurator: ComputeConfiguration.() -> Unit): ComputeAction {
		return compute(updateLocation(destination.location, "tag/")) {
			target = Either.right(destination)
			add(ComputeAction.Value(Either.right(source), IMatterFunction.PLUS))
			configurator.invoke(this)
		}
	}

	// multiplied inheritance
	fun inherit(destination: ItemLike, source: ItemLike, multiplier: Double, configurator: ComputeConfiguration.() -> Unit): ComputeAction {
		return inherit(destination, source) {
			add(ComputeAction.Constant(Decimal(multiplier), multiplier, IMatterFunction.MUL))
			configurator.invoke(this)
		}
	}

	fun inherit(destination: TagKey<Item>, source: ItemLike, multiplier: Double, configurator: ComputeConfiguration.() -> Unit): ComputeAction {
		return inherit(destination, source) {
			add(ComputeAction.Constant(Decimal(multiplier), multiplier, IMatterFunction.MUL))
			configurator.invoke(this)
		}
	}

	fun inherit(destination: ItemLike, source: TagKey<Item>, multiplier: Double, configurator: ComputeConfiguration.() -> Unit): ComputeAction {
		return inherit(destination, source) {
			add(ComputeAction.Constant(Decimal(multiplier), multiplier, IMatterFunction.MUL))
			configurator.invoke(this)
		}
	}

	fun inherit(destination: TagKey<Item>, source: TagKey<Item>, multiplier: Double, configurator: ComputeConfiguration.() -> Unit): ComputeAction {
		return inherit(destination, source) {
			add(ComputeAction.Constant(Decimal(multiplier), multiplier, IMatterFunction.MUL))
			configurator.invoke(this)
		}
	}

	fun inherit(destination: ItemLike, source: ItemLike, multiplier: Decimal, configurator: ComputeConfiguration.() -> Unit): ComputeAction {
		return inherit(destination, source) {
			add(ComputeAction.Constant(multiplier, multiplier.toDouble(), IMatterFunction.MUL))
			configurator.invoke(this)
		}
	}

	fun inherit(destination: TagKey<Item>, source: ItemLike, multiplier: Decimal, configurator: ComputeConfiguration.() -> Unit): ComputeAction {
		return inherit(destination, source) {
			add(ComputeAction.Constant(multiplier, multiplier.toDouble(), IMatterFunction.MUL))
			configurator.invoke(this)
		}
	}

	fun inherit(destination: ItemLike, source: TagKey<Item>, multiplier: Decimal, configurator: ComputeConfiguration.() -> Unit): ComputeAction {
		return inherit(destination, source) {
			add(ComputeAction.Constant(multiplier, multiplier.toDouble(), IMatterFunction.MUL))
			configurator.invoke(this)
		}
	}

	fun inherit(destination: TagKey<Item>, source: TagKey<Item>, multiplier: Decimal, configurator: ComputeConfiguration.() -> Unit): ComputeAction {
		return inherit(destination, source) {
			add(ComputeAction.Constant(multiplier, multiplier.toDouble(), IMatterFunction.MUL))
			configurator.invoke(this)
		}
	}

	// java friendly inheritance
	@JvmOverloads
	fun inherit(destination: ItemLike, source: ItemLike, configurator: Consumer<ComputeConfiguration> = Consumer { }): ComputeAction {
		return inherit(destination, source, configurator::accept)
	}

	@JvmOverloads
	fun inherit(destination: TagKey<Item>, source: ItemLike, configurator: Consumer<ComputeConfiguration> = Consumer { }): ComputeAction {
		return inherit(destination, source, configurator::accept)
	}

	@JvmOverloads
	fun inherit(destination: ItemLike, source: TagKey<Item>, configurator: Consumer<ComputeConfiguration> = Consumer { }): ComputeAction {
		return inherit(destination, source, configurator::accept)
	}

	@JvmOverloads
	fun inherit(destination: TagKey<Item>, source: TagKey<Item>, configurator: Consumer<ComputeConfiguration> = Consumer { }): ComputeAction {
		return inherit(destination, source, configurator::accept)
	}

	@JvmOverloads
	fun inherit(destination: ItemLike, source: ItemLike, multiplier: Double, configurator: Consumer<ComputeConfiguration> = Consumer { }): ComputeAction {
		return inherit(destination, source, multiplier, configurator::accept)
	}

	@JvmOverloads
	fun inherit(destination: TagKey<Item>, source: ItemLike, multiplier: Double, configurator: Consumer<ComputeConfiguration> = Consumer { }): ComputeAction {
		return inherit(destination, source, multiplier, configurator::accept)
	}

	@JvmOverloads
	fun inherit(destination: ItemLike, source: TagKey<Item>, multiplier: Double, configurator: Consumer<ComputeConfiguration> = Consumer { }): ComputeAction {
		return inherit(destination, source, multiplier, configurator::accept)
	}

	@JvmOverloads
	fun inherit(destination: TagKey<Item>, source: TagKey<Item>, multiplier: Double, configurator: Consumer<ComputeConfiguration> = Consumer { }): ComputeAction {
		return inherit(destination, source, multiplier, configurator::accept)
	}

	@JvmOverloads
	fun inherit(destination: ItemLike, source: ItemLike, multiplier: Decimal, configurator: Consumer<ComputeConfiguration> = Consumer { }): ComputeAction {
		return inherit(destination, source, multiplier, configurator::accept)
	}

	@JvmOverloads
	fun inherit(destination: TagKey<Item>, source: ItemLike, multiplier: Decimal, configurator: Consumer<ComputeConfiguration> = Consumer { }): ComputeAction {
		return inherit(destination, source, multiplier, configurator::accept)
	}

	@JvmOverloads
	fun inherit(destination: ItemLike, source: TagKey<Item>, multiplier: Decimal, configurator: Consumer<ComputeConfiguration> = Consumer { }): ComputeAction {
		return inherit(destination, source, multiplier, configurator::accept)
	}

	@JvmOverloads
	fun inherit(destination: TagKey<Item>, source: TagKey<Item>, multiplier: Decimal, configurator: Consumer<ComputeConfiguration> = Consumer { }): ComputeAction {
		return inherit(destination, source, multiplier, configurator::accept)
	}

	fun insert(name: ItemLike, configurator: InsertConfiguration.() -> Unit): InsertAction {
		return insert(updateLocation(name.asItem().registryName ?: throw NullPointerException("${name.asItem()} does not have registry name!"), "item/")) {
			target = Either.left(name.asItem().registryName!!)
			configurator.invoke(this)
		}
	}

	fun delete(name: ItemLike, configurator: DeleteConfiguration.() -> Unit): DeleteAction {
		return delete(updateLocation(name.asItem().registryName ?: throw NullPointerException("${name.asItem()} does not have registry name!"), "item/")) {
			target = Either.left(name.asItem().registryName!!)
			configurator.invoke(this)
		}
	}

	fun blacklist(name: ItemLike): BlacklistAction {
		return blacklist(updateLocation(name.asItem().registryName ?: throw NullPointerException("${name.asItem()} does not have registry name!"), "item/")) {
			target = Either.left(name.asItem().registryName!!)
		}
	}

	fun blacklist(name: TagKey<Item>): BlacklistAction {
		return blacklist(updateLocation(name.location, "tag/")) {
			target = Either.right(name)
		}
	}

	fun update(name: ItemLike, configurator: UpdateConfiguration.() -> Unit): UpdateAction {
		return update(updateLocation(name.asItem().registryName ?: throw NullPointerException("${name.asItem()} does not have registry name!"), "item/")) {
			target = Either.left(name.asItem().registryName!!)
			configurator.invoke(this)
		}
	}

	fun insert(name: TagKey<Item>, configurator: InsertConfiguration.() -> Unit): InsertAction {
		return insert(updateLocation(name.location, "tag/")) {
			target = Either.right(name)
			configurator.invoke(this)
		}
	}

	fun delete(name: TagKey<Item>, configurator: DeleteConfiguration.() -> Unit): DeleteAction {
		return delete(updateLocation(name.location, "tag/")) {
			target = Either.right(name)
			configurator.invoke(this)
		}
	}

	fun update(name: TagKey<Item>, configurator: UpdateConfiguration.() -> Unit): UpdateAction {
		return update(updateLocation(name.location, "tag/")) {
			target = Either.right(name)
			configurator.invoke(this)
		}
	}

	fun insert(name: ResourceLocation, 	configurator: Consumer<InsertConfiguration>) = insert(name, configurator::accept)
	fun delete(name: ResourceLocation, 	configurator: Consumer<DeleteConfiguration>) = delete(name, configurator::accept)
	fun update(name: ResourceLocation, 	configurator: Consumer<UpdateConfiguration>) = update(name, configurator::accept)
	fun insert(name: ItemLike, 			configurator: Consumer<InsertConfiguration>) = insert(name, configurator::accept)
	fun delete(name: ItemLike, 			configurator: Consumer<DeleteConfiguration>) = delete(name, configurator::accept)
	fun update(name: ItemLike, 			configurator: Consumer<UpdateConfiguration>) = update(name, configurator::accept)
	fun insert(name: TagKey<Item>, 		configurator: Consumer<InsertConfiguration>) = insert(name, configurator::accept)
	fun delete(name: TagKey<Item>, 		configurator: Consumer<DeleteConfiguration>) = delete(name, configurator::accept)
	fun update(name: TagKey<Item>, 		configurator: Consumer<UpdateConfiguration>) = update(name, configurator::accept)

	fun insert(name: ResourceLocation, matterValue: Decimal, complexity: Double, configurator: InsertConfiguration.() -> Unit) = insert(name) {
		this.matter = matterValue
		this.complexity = complexity
		configurator.invoke(this)
	}

	fun insert(name: ItemLike, matterValue: Decimal, complexity: Double, configurator: InsertConfiguration.() -> Unit) = insert(name) {
		this.matter = matterValue
		this.complexity = complexity
		configurator.invoke(this)
	}

	fun insert(name: TagKey<Item>, matterValue: Decimal, complexity: Double, configurator: InsertConfiguration.() -> Unit) = insert(name) {
		this.matter = matterValue
		this.complexity = complexity
		configurator.invoke(this)
	}

	fun insert(name: ResourceLocation, matterValue: Decimal, complexity: Double, priority: Int, configurator: InsertConfiguration.() -> Unit) = insert(name) {
		this.matter = matterValue
		this.complexity = complexity
		this.priority = priority
		configurator.invoke(this)
	}

	fun insert(name: ItemLike, matterValue: Decimal, complexity: Double, priority: Int, configurator: InsertConfiguration.() -> Unit) = insert(name) {
		this.matter = matterValue
		this.complexity = complexity
		this.priority = priority
		configurator.invoke(this)
	}

	fun insert(name: TagKey<Item>, matterValue: Decimal, complexity: Double, priority: Int, configurator: InsertConfiguration.() -> Unit) = insert(name) {
		this.matter = matterValue
		this.complexity = complexity
		this.priority = priority
		configurator.invoke(this)
	}

	@JvmOverloads
	fun insert(name: ResourceLocation, matterValue: Decimal, complexity: Double, configurator: Consumer<InsertConfiguration> = Consumer {  }) = insert(name, matterValue, complexity, configurator::accept)
	@JvmOverloads
	fun insert(name: ItemLike, matterValue: Decimal, complexity: Double, configurator: Consumer<InsertConfiguration> = Consumer {  }) = insert(name, matterValue, complexity, configurator::accept)
	@JvmOverloads
	fun insert(name: TagKey<Item>, matterValue: Decimal, complexity: Double, configurator: Consumer<InsertConfiguration> = Consumer {  }) = insert(name, matterValue, complexity, configurator::accept)

	@JvmOverloads
	fun insert(name: ResourceLocation, matterValue: Decimal, complexity: Double, priority: Int, configurator: Consumer<InsertConfiguration> = Consumer {  }) = insert(name, matterValue, complexity, priority, configurator::accept)
	@JvmOverloads
	fun insert(name: ItemLike, matterValue: Decimal, complexity: Double, priority: Int, configurator: Consumer<InsertConfiguration> = Consumer {  }) = insert(name, matterValue, complexity, priority, configurator::accept)
	@JvmOverloads
	fun insert(name: TagKey<Item>, matterValue: Decimal, complexity: Double, priority: Int, configurator: Consumer<InsertConfiguration> = Consumer {  }) = insert(name, matterValue, complexity, priority, configurator::accept)

	/**
	 * Override this if you prefer The Mundane Way™ instead of calling [insert], [delete] and [update] directly
	 *
	 * Called inside [run]
	 */
	protected open fun addActions() {}

	protected val added = ArrayList<AbstractRegistryAction>()
	val addedView: List<AbstractRegistryAction> = Collections.unmodifiableList(added)

	final override fun run(output: CachedOutput): CompletableFuture<*> {
		addActions()

		val promises = ArrayList<CompletableFuture<*>>()

		for ((key, value) in actions) {
			promises.add(DataProvider.saveStable(output, AbstractRegistryAction.CODEC.toJsonStrict(value), pathProvider.json(key)))
			added.add(value)
		}

		return CompletableFuture.allOf(*promises.toTypedArray())
	}

	override fun getName(): String {
		if (modid != null)
			return "Matter Data for mod $modid"

		return "Matter Data"
	}
}
