PassOwnPtr<InterpolationValue> CSSImageListInterpolationType::maybeConvertNeutral(const UnderlyingValue& underlyingValue, ConversionCheckers& conversionCheckers) const
{
    if (!underlyingValue) {
        conversionCheckers.append(UnderlyingImageListChecker::create(*this, nullptr));
        return nullptr;
    }
    conversionCheckers.append(UnderlyingImageListChecker::create(*this, underlyingValue->clone()));
    return underlyingValue->clone();
}
InterpolationValue CSSPaintInterpolationType::maybeConvertInherit(const StyleResolverState& state, ConversionCheckers& conversionCheckers) const
{
    if (!state.parentStyle())
        return nullptr;
    StyleColor parentColor;
    if (!PaintPropertyFunctions::getColor(cssProperty(), *state.parentStyle(), parentColor)) {
        conversionCheckers.append(ParentPaintChecker::create(cssProperty()));
        return nullptr;
    }
    conversionCheckers.append(ParentPaintChecker::create(cssProperty(), parentColor));
    return InterpolationValue(CSSColorInterpolationType::createInterpolableColor(parentColor));
}
InterpolationValue CSSBasicShapeInterpolationType::maybeConvertInherit(const StyleResolverState& state, ConversionCheckers& conversionCheckers) const
{
    const BasicShape* shape = BasicShapePropertyFunctions::getBasicShape(cssProperty(), *state.parentStyle());
    // const_cast to take a ref.
    conversionCheckers.append(InheritedShapeChecker::create(cssProperty(), const_cast<BasicShape*>(shape)));
    return BasicShapeInterpolationFunctions::maybeConvertBasicShape(shape, state.parentStyle()->effectiveZoom());
}
InterpolationValue CSSBasicShapeInterpolationType::maybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers& conversionCheckers) const
{
    // const_cast is for taking refs.
    NonInterpolableValue* nonInterpolableValue = const_cast<NonInterpolableValue*>(underlying.nonInterpolableValue.get());
    conversionCheckers.append(UnderlyingCompatibilityChecker::create(nonInterpolableValue));
    return InterpolationValue(BasicShapeInterpolationFunctions::createNeutralValue(*underlying.nonInterpolableValue), nonInterpolableValue);
}
InterpolationValue CSSScaleInterpolationType::maybeConvertInherit(
    const StyleResolverState& state,
    ConversionCheckers& conversionCheckers) const {
  Scale parentScale(state.parentStyle()->scale());
  conversionCheckers.append(ParentScaleChecker::create(parentScale));
  return InterpolationValue(parentScale.createInterpolableValue());
}
InterpolationValue CSSTransformInterpolationType::maybeConvertValue(
    const CSSValue& value,
    const StyleResolverState& state,
    ConversionCheckers& conversionCheckers) const {
  if (value.isValueList()) {
    CSSLengthArray lengthArray;
    for (const CSSValue* item : toCSSValueList(value)) {
      const CSSFunctionValue& transformFunction = toCSSFunctionValue(*item);
      if (transformFunction.functionType() == CSSValueMatrix ||
          transformFunction.functionType() == CSSValueMatrix3d) {
        lengthArray.typeFlags.set(CSSPrimitiveValue::UnitTypePixels);
        continue;
      }
      for (const CSSValue* argument : transformFunction) {
        const CSSPrimitiveValue& primitiveValue =
            toCSSPrimitiveValue(*argument);
        if (!primitiveValue.isLength())
          continue;
        primitiveValue.accumulateLengthArray(lengthArray);
      }
    }
    std::unique_ptr<InterpolationType::ConversionChecker> lengthUnitsChecker =
        LengthUnitsChecker::maybeCreate(std::move(lengthArray), state);

    if (lengthUnitsChecker)
      conversionCheckers.append(std::move(lengthUnitsChecker));
  }

  TransformOperations transform;
  TransformBuilder::createTransformOperations(
      value, state.cssToLengthConversionData(), transform);
  return convertTransform(std::move(transform));
}
PassOwnPtr<InterpolationValue> CSSShadowListInterpolationType::maybeConvertInherit(const StyleResolverState& state, ConversionCheckers& conversionCheckers) const
{
    if (!state.parentStyle())
        return nullptr;
    const ShadowList* parentShadowList = ShadowListPropertyFunctions::getShadowList(cssProperty(), *state.parentStyle());
    conversionCheckers.append(ParentShadowListChecker::create(*this, cssProperty(), const_cast<ShadowList*>(parentShadowList))); // Take ref.
    return convertShadowList(parentShadowList, state.parentStyle()->effectiveZoom());
}
InterpolationValue CSSClipInterpolationType::maybeConvertInherit(const StyleResolverState& state, ConversionCheckers& conversionCheckers) const
{
    ClipAutos parentAutos = getClipAutos(*state.parentStyle());
    conversionCheckers.append(ParentAutosChecker::create(parentAutos));
    if (parentAutos.isAuto)
        return nullptr;
    return createClipValue(state.parentStyle()->clip(), state.parentStyle()->effectiveZoom());
}