/**
  * {inheritdoc}
  */
 public function serialize($value, array $formatters)
 {
     if (!is_object($value)) {
         return [];
     }
     $evaluator = new ObjectFieldEvaluator($value);
     $value1 = $this->builtin !== null ? $this->builtin->serialize($value, $formatters) : [];
     $value2 = array_reduce(array_keys($this->strategies), function (&$tmp, $f) use($evaluator, $formatters) {
         list($valid, $v) = $evaluator->evaluateField($f);
         return $valid ? $tmp + [$f => $this->strategies[$f]->serialize($v, $formatters)] : $tmp;
     }, []);
     return $value1 + $value2;
 }
 /**
  * {inheritdoc}
  */
 public function serialize($value, array $formatters)
 {
     if (!is_array($value)) {
         return [];
     }
     if (is_object(current($value))) {
         if ($this->strategy != null) {
             return array_map(function ($obj) use($formatters) {
                 return $this->strategy->serialize($obj, $formatters);
             }, $value);
         } else {
             return array_map(function ($obj) use($formatters) {
                 $class = get_class($obj);
                 if (!isset($formatters[$class])) {
                     throw new \Exception("formatter is not found (type: {$class})");
                 }
                 return $formatters[$class]->format($obj);
             }, $value);
         }
     }
     return $value;
 }
 /**
  * @return mixed
  */
 public function jsonSerialize()
 {
     return $this->strategy->serialize($this->value, $this->formatters);
 }