protected function configureElement($annotations, $reflection, $formSpec, $filterSpec)
    {
        // If the element is marked as exclude, return early
        if ($this->checkForExclude($annotations)) {
            return;
        }

        $events = $this->getEventManager();
        $name   = $this->discoverName($annotations, $reflection);

        $elementSpec = new ArrayObject([
                'flags' => [],
                'spec'  => [
                    'name' => $name
                ],
            ]);

        $inputSpec = new ArrayObject([
                'name' => $name,
            ]);

        $event = new Event();
        $event->setParams([
                'name'        => $name,
                'elementSpec' => $elementSpec,
                'inputSpec'   => $inputSpec,
                'formSpec'    => $formSpec,
                'filterSpec'  => $filterSpec,
            ]);

        foreach ($annotations as $annotation) {
            $event->setParam('annotation', $annotation);
            $events->trigger(__FUNCTION__, $this, $event);
        }

        // Since "filters", "type", "validators" is a reserved names in the filter specification,
        // we need to add the specification without the name as the key.
        // In all other cases, though, the name is fine.
        if ($event->getParam('inputSpec')->count() > 1 || $annotations->hasAnnotation(Input::class)) {
            if ($name === 'type' || $name === 'filters' || $name === 'validators') {
                $filterSpec[] = $event->getParam('inputSpec');
            } else {
                $filterSpec[$name] = $event->getParam('inputSpec');
            }
        }

        $elementSpec = $event->getParam('elementSpec');
        $type = isset($elementSpec['spec']['type'])
            ? $elementSpec['spec']['type']
            : Element::class;

        // Compose as a fieldset or an element, based on specification type.
        // If preserve defined order is true, all elements are composed as elements to keep their ordering
        if (!$this->preserveDefinedOrder() && is_subclass_of($type, FieldsetInterface::class)) {
            if (!isset($formSpec['fieldsets'])) {
                $formSpec['fieldsets'] = [];
            }

            if (isset($formSpec['fieldsets'][$name])) {
                $formSpec['fieldsets'][] = $elementSpec;
            } else {
                $formSpec['fieldsets'][$name] = $elementSpec;
            }

        } else {
            if (!isset($formSpec['elements'])) {
                $formSpec['elements'] = [];
            }

            if (isset($formSpec['elements'][$name])) {
                $formSpec['elements'][] = $elementSpec;
            } else {
                $formSpec['elements'][$name] = $elementSpec;
            }
        }
    }