protected function validate(GeneratorData $data)
    {
        $source = $data->getSource();

        if (!(is_array($source) && isset($source[self::NODE_ACTIONS]) && is_array($source[self::NODE_ACTIONS]))) {
            throw new SyntaxException(sprintf('expected array with "%s" node', self::NODE_ACTIONS), $source);
        }

        $actions = $source[self::NODE_ACTIONS];
        foreach ($actions as $nodeNo => $actionDefinition) {
            if (isset($actionDefinition[self::PATH_ATTR])) {
                $path = $actionDefinition[self::PATH_ATTR];
                unset($actionDefinition[self::PATH_ATTR]);
            } else {
                $path = self::NODE_ACTIONS . '.' . $nodeNo;
            }

            if (!is_array($actionDefinition)) {
                throw new SyntaxException('expected array with action name as key', $actionDefinition, $path);
            }

            $actionName = key($actionDefinition);
            $arguments  = is_array($actionDefinition[$actionName])
                ? $actionDefinition[$actionName] : [$actionDefinition[$actionName]];

            if (strpos($actionName, '@') !== 0) {
                throw new SyntaxException(
                    sprintf('action name should start with "@" symbol, current name "%s"', $actionName),
                    $actionDefinition,
                    $path
                );
            }

            $this->normalizeActionName($actionName);

            if (!$this->getHelper()->hasMethod($actionName)) {
                throw new SyntaxException(
                    sprintf('unknown action "%s", should be one of LayoutManipulatorInterface\'s methods', $actionName),
                    $actionDefinition,
                    $path
                );
            }

            if (!$this->getHelper()->isValidArguments($actionName, $arguments)) {
                throw new SyntaxException($this->getHelper()->getLastError(), $actionDefinition, $path);
            }
        }
    }