public function renderBody()
	{
		$translator = $this->form->getTranslator();

		// first render groups. They will mark their controls as rendered
		$groups = Html::el();
		foreach ($this->form->getGroups() as $group) {
			if (!$group->getControls() || !$group->getOption(RendererOptions::visual)) {
				continue;
			}

			//region getting container
			$container = $group->getOption(RendererOptions::container, NULL);
			if (is_string($container)) {
				$container = $this->configElem(Cnf::group, Html::el($container));
			} elseif ($container instanceof Html) {
				$container = $this->configElem(Cnf::group, $container);
			} else {
				$container = $this->getElem(Cnf::group);
			}

			$container->setAttribute('id', $group->getOption(RendererOptions::id));

			//endregion

			//region label
			$label = $group->getOption(RendererOptions::label);
			if ($label instanceof Html) {
				$label = $this->configElem(Cnf::groupLabel, $label);
			} elseif (is_string($label)) {
				if ($translator !== NULL) {
					$label = $translator->translate($label);
				}
				$labelHtml = $this->getElem(Cnf::groupLabel);
				$labelHtml->setText($label);
				$label = $labelHtml;
			}
			//endregion

			if (!empty($label)) {
				$container->addHtml($label);
			}

			$controls = $this->renderControls($group);
			if (!empty($controls)) {
				$container->addHtml($controls);
			}

			$groups->addHtml($container);
		}
		// we now know which ones to skip, so render the rest
		$formControls = $this->renderControls($this->form);

		$out = Html::el();
		if (!empty($formControls)) {
			$out->addHtml($formControls);
		}
		if (!empty($groups)) {
			$out->addHtml($groups);
		}

		return $out;
	}