protected function createTaxTypeFromDefinition(array $definition)
    {
        // Load the referenced zone.
        $definition['zone'] = $this->zoneRepository->get($definition['zone']);
        // Provide defaults.
        if (!isset($definition['compound'])) {
            $definition['compound'] = false;
        }
        if (!isset($definition['display_inclusive'])) {
            $definition['display_inclusive'] = false;
        }
        if (!isset($definition['rounding_mode'])) {
            $definition['rounding_mode'] = PHP_ROUND_HALF_UP;
        }

        $type = new TaxType();
        // Bind the closure to the TaxType object, giving it access to
        // its protected properties. Faster than both setters and reflection.
        $setValues = \Closure::bind(function ($definition) {
            $this->id = $definition['id'];
            $this->name = $definition['name'];
            $this->compound = $definition['compound'];
            $this->displayInclusive = $definition['display_inclusive'];
            $this->roundingMode = $definition['rounding_mode'];
            $this->zone = $definition['zone'];
            if (isset($definition['generic_label'])) {
                $this->genericLabel = $definition['generic_label'];
            }
            if (isset($definition['tag'])) {
                $this->tag = $definition['tag'];
            }
        }, $type, '\CommerceGuys\Tax\Model\TaxType');
        $setValues($definition);

        foreach ($definition['rates'] as $rateDefinition) {
            $rate = $this->createTaxRateFromDefinition($rateDefinition);
            $type->addRate($rate);
        }

        return $type;
    }