protected function addService(
        $id,
        $parent = null,
        array $calls = [],
        $tag = null,
        array $arguments = [],
        $factoryService = null,
        $factoryMethod = null,
        $className = null
    ) {
        $service = [];
        $service['public'] = true;

        // classname
        if (is_null($className)) {
            $className = '%' . $id . '.class%';
        }
        $service['class'] = $className;

        // parent
        if (!is_null($parent)) {
            $service['parent'] = $parent;
        }

        // factory
        if ($factoryService && $factoryMethod) {
            $service['factory'] = [
                '@'.$factoryService,
                $factoryMethod
            ];
        }

        foreach ($arguments as $argument) {
            if ($argument['type'] == 'service') {
                $service['arguments'][] = '@'.$argument['id'];
            } else {
                $service['arguments'][] = $argument['value'];
            }
        }

        // calls
        foreach ($calls as $call) {
            $service['calls'][] = [
                $call['method'],
                ['@'.$call['service']]
            ];
        }

        // tags
        if ($tag) {
            $thisTag = [
                'name' => $tag
            ];

            if ($this->json instanceof JsonDefinition) {
                $thisTag['collection'] = $this->json->getId();

                // is this read only?
                if ($this->json->isReadOnlyService()) {
                    $thisTag['read-only'] = true;
                }

                // router base defined?
                $routerBase = $this->json->getRouterBase();
                if ($routerBase !== false) {
                    $thisTag['router-base'] = $routerBase;
                }
            }

            $service['tags'][] = $thisTag;
        }

        $this->services['services'][$id] = $service;
    }