public function updateAttributesAndFeaturesAction($productId)
    {
        $product = ProductQuery::create()->findPk($productId);

        if ($product != null) {
            $featureTemplate = FeatureTemplateQuery::create()->filterByTemplateId($product->getTemplateId())->find();

            if ($featureTemplate !== null) {
                // Get all features for the template attached to this product
                $allFeatures = FeatureQuery::create()
                    ->filterByFeatureTemplate($featureTemplate)
                    ->find();

                $updatedFeatures = array();

                // Update all features values, starting with feature av. values
                $featureValues = $this->getRequest()->get('feature_value', array());

                foreach ($featureValues as $featureId => $featureValueList) {
                    // Delete all features av. for this feature.
                    $event = new FeatureProductDeleteEvent($productId, $featureId);

                    $this->dispatch(TheliaEvents::PRODUCT_FEATURE_DELETE_VALUE, $event);

                    // Add then all selected values
                    foreach ($featureValueList as $featureValue) {
                        $event = new FeatureProductUpdateEvent($productId, $featureId, $featureValue);

                        $this->dispatch(TheliaEvents::PRODUCT_FEATURE_UPDATE_VALUE, $event);
                    }

                    $updatedFeatures[] = $featureId;
                }

                // Update then features text values
                $featureTextValues = $this->getRequest()->get('feature_text_value', array());

                foreach ($featureTextValues as $featureId => $featureValue) {
                    // Check if a FeatureProduct exists for this product and this feature (for another lang)
                    $freeTextFeatureProduct = FeatureProductQuery::create()
                        ->filterByProductId($productId)
                        ->filterByIsFreeText(true)
                        ->findOneByFeatureId($featureId);

                    // If no corresponding FeatureProduct exists AND if the feature_text_value is empty, do nothing
                    if (\is_null($freeTextFeatureProduct) && empty($featureValue)) {
                        continue;
                    }

                    $event = new FeatureProductUpdateEvent($productId, $featureId, $featureValue, true);
                    $event->setLocale($this->getCurrentEditionLocale());

                    $this->dispatch(TheliaEvents::PRODUCT_FEATURE_UPDATE_VALUE, $event);

                    $updatedFeatures[] = $featureId;
                }

                // Delete features which don't have any values
                /** @var Feature $feature */
                foreach ($allFeatures as $feature) {
                    if (! \in_array($feature->getId(), $updatedFeatures)) {
                        $event = new FeatureProductDeleteEvent($productId, $feature->getId());

                        $this->dispatch(TheliaEvents::PRODUCT_FEATURE_DELETE_VALUE, $event);
                    }
                }
            }
        }

        // If we have to stay on the same page, do not redirect to the successUrl,
        // just redirect to the edit page again.
        if ($this->getRequest()->get('save_mode') == 'stay') {
            return $this->redirectToEditionTemplate();
        }

        // Redirect to the category/product list
        return $this->redirectToListTemplate();
    }