public static function fromHsl($hue, $saturation, $lightness, $alpha = 1.0)
    {
        if ($hue < 0) $hue = 0;
        if ($hue > 1) $hue = 1;
        
        if ($saturation < 0) $saturation = 0;
        if ($saturation > 1) $saturation = 1;
        
        if ($lightness < 0) $lightness = 0;
        if ($lightness > 1) $lightness = 1;
        
        if ($alpha < 0) $alpha = 0;
        if ($alpha > 1) $alpha = 1;

        // Based on http://www.w3.org/TR/2011/REC-css3-color-20110607/#hsl-color
        if ($saturation == 0) {
            $value = (int)($lightness * 255);
            return self::fromRgb($value, $value, $value, (int)($alpha * 255));
        } else {
            if ($lightness <= 0.5) {
                $m2 = $lightness * ($saturation + 1);
            } else {
                $m2 = $lightness + $saturation - $lightness * $saturation;
            }
            
            $m1 = $lightness * 2 - $m2;

            return self::fromRgb(
                self::hueToRgb($m1, $m2, $hue * 6 + 2),
                self::hueToRgb($m1, $m2, $hue * 6),
                self::hueToRgb($m1, $m2, $hue * 6 - 2),
                (int)($alpha * 255));
        }
    }