diff --git a/core/lib/Drupal/Component/Gettext/PoHeader.php b/core/lib/Drupal/Component/Gettext/PoHeader.php
index 44959eb..cf9e5d5 100644
--- a/core/lib/Drupal/Component/Gettext/PoHeader.php
+++ b/core/lib/Drupal/Component/Gettext/PoHeader.php
@@ -215,9 +215,11 @@ function parsePluralForms($pluralforms) {
     }
 
     // Get PHP version of the plural formula.
-    $plural = $this->parseArithmetic($plural);
-
-    if ($plural !== FALSE) {
+    $element_stack = $this->parseArithmetic($plural);
+    if ($element_stack !== FALSE) {
+      for ($i = 0; $i < 199; $i++) {
+        $plural[$i] = $this->evaluatePlural($element_stack, $i);
+      }
       return array($nplurals, $plural);
     }
     else {
@@ -319,8 +321,9 @@ private function parseArithmetic($string) {
       $element_stack[] = $topop;
       $topop = array_pop($operator_stack);
     }
+    $return = $element_stack;
 
-    // Now extract formula from stack.
+    // Now validate stack.
     $previous_size = count($element_stack) + 1;
     while (count($element_stack) < $previous_size) {
       $previous_size = count($element_stack);
@@ -344,12 +347,7 @@ private function parseArithmetic($string) {
     }
 
     // If only one element is left, the number of operators is appropriate.
-    if (count($element_stack) == 1) {
-      return $element_stack[0];
-    }
-    else {
-      return FALSE;
-    }
+    return count($element_stack) == 1 ? $return : FALSE;
   }
 
   /**
@@ -417,4 +415,76 @@ private function tokenizeFormula($formula) {
     return $tokens;
   }
 
+  /**
+   * @todo
+   * @param $element_stack
+   * @param $n
+   *
+   * @return mixed
+   */
+  protected function evaluatePlural($element_stack, $n) {
+    $previous_size = count($element_stack) + 1;
+    while (count($element_stack) < $previous_size) {
+      $previous_size = count($element_stack);
+      for ($i = 2; $i < count($element_stack); $i++) {
+        $f = NULL;
+        $length = 3;
+        $delta = 2;
+        switch ($element_stack[$i]) {
+          case '$n':
+            $element_stack[$i] = $n;
+            continue 2;
+          case '==':
+            $f = $element_stack[$i - 2] == $element_stack[$i - 1];
+            break;
+          case '!=':
+            $f = $element_stack[$i - 2] != $element_stack[$i - 1];
+            break;
+          case '<=':
+            $f = $element_stack[$i - 2] <= $element_stack[$i - 1];
+            break;
+          case '>=':
+            $f = $element_stack[$i - 2] >= $element_stack[$i - 1];
+            break;
+          case '<':
+            $f = $element_stack[$i - 2] < $element_stack[$i - 1];
+            break;
+          case '>':
+            $f = $element_stack[$i - 2] > $element_stack[$i - 1];
+            break;
+          case '+':
+            $f = $element_stack[$i - 2] + $element_stack[$i - 1];
+            break;
+          case '-':
+            $f = $element_stack[$i - 2] - $element_stack[$i - 1];
+            break;
+          case '*':
+            $f = $element_stack[$i - 2] * $element_stack[$i - 1];
+            break;
+          case '/':
+            $f = $element_stack[$i - 2] / $element_stack[$i - 1];
+            break;
+          case '%':
+            $f = $element_stack[$i - 2] % $element_stack[$i - 1];
+            break;
+          case '&&':
+            $f = $element_stack[$i - 2] && $element_stack[$i - 1];
+            break;
+          case '||':
+            $f = $element_stack[$i - 2] || $element_stack[$i - 1];
+            break;
+          case ':':
+            $f = $element_stack[$i - 3] ? $element_stack[$i - 2] : $element_stack[$i - 1];
+            // Remove bool, left, right, :, ?
+            $length = 5;
+            $delta = 3;
+            break;
+        }
+        if (isset($f))
+          array_splice($element_stack, $i - $delta, $length, $f);
+        break;
+      }
+    }
+    return $element_stack[0];
+  }
 }
diff --git a/core/modules/locale/lib/Drupal/locale/PoDatabaseWriter.php b/core/modules/locale/lib/Drupal/locale/PoDatabaseWriter.php
index b28748a..eebf85a 100644
--- a/core/modules/locale/lib/Drupal/locale/PoDatabaseWriter.php
+++ b/core/modules/locale/lib/Drupal/locale/PoDatabaseWriter.php
@@ -178,7 +178,7 @@ function setHeader(PoHeader $header) {
         list($nplurals, $formula) = $p;
         $locale_plurals[$langcode] = array(
           'plurals' => $nplurals,
-          'formula' => $formula,
+          'formula' =>  serialize($formula),
         );
         \Drupal::state()->set('locale.translation.plurals', $locale_plurals);
       }
diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module
index dcca8bf..1515476 100644
--- a/core/modules/locale/locale.module
+++ b/core/modules/locale/locale.module
@@ -379,9 +379,12 @@ function locale_get_plural($count, $langcode = NULL) {
     // $count and statically cache the result for the combination of language
     // and count, since the result will always be identical.
     if (!empty($plural_formulas[$langcode])) {
-      // $n is used inside the expression in the eval().
-      $n = $count;
-      $plural_indexes[$langcode][$count] = @eval('return intval(' . $plural_formulas[$langcode]['formula'] . ');');
+      // Plural formulas are stored as an array for 0-199. 100 is the highest
+      // modulo used but storing 0-99 is not enough because below 100 we often
+      // find exceptions (1, 2, etc).
+      $index = $count > 199 ? 100 + ($count % 100) : $count;
+      $plural_indexes[$langcode][$count] = $plural_formulas[$langcode]['formula'][$index];
+
     }
     // In case there is no plural formula for English (no imported translation
     // for English), use a default formula.
