public static function build(MetaClass $class)
    {
        $out = self::getHead();
        $type = $class->getType();
        if ($type) {
            switch ($type->getId()) {
                case MetaClassType::CLASS_ABSTRACT:
                    $abstract = 'abstract ';
                    $notes = 'nothing here yet';
                    break;
                case MetaClassType::CLASS_FINAL:
                    $abstract = 'final ';
                    $notes = 'last chance for customization';
                    break;
                default:
                    throw new WrongStateException('unknown class type');
            }
        } else {
            $abstract = null;
            $notes = 'your brilliant stuff goes here';
        }
        $out .= <<<EOT
{$abstract}class {$class->getName()}DAO extends Auto{$class->getName()}DAO
{
\t// {$notes}
}

EOT;
        return $out . self::getHeel();
    }
    public static function build(MetaClass $class)
    {
        $out = self::getHead();
        if ($type = $class->getType()) {
            $typeName = $type->toString() . ' ';
        } else {
            $typeName = null;
        }
        $out .= <<<EOT
{$typeName}class Proto{$class->getName()} extends AutoProto{$class->getName()} {/*_*/}

EOT;
        return $out . self::getHeel();
    }
    public static function build(MetaClass $class)
    {
        $out = self::getHead();
        if ($type = $class->getType()) {
            $type = "{$type->getName()} ";
        } else {
            $type = null;
        }
        $out .= <<<EOT
{$type}class {$class->getName()} extends Enumeration
{
\t// implement me!
}

EOT;
        return $out . self::getHeel();
    }
 /**
  * @return MetaConfiguration
  **/
 private function checkSanity(MetaClass $class)
 {
     if ((!$class->getParent() || $class->getFinalParent()->getPattern() instanceof InternalClassPattern) && !$class->getPattern() instanceof ValueObjectPattern && !$class->getPattern() instanceof InternalClassPattern) {
         Assert::isTrue($class->getIdentifier() !== null, 'only value objects can live without identifiers. ' . 'do not use them anyway (' . $class->getName() . ')');
     }
     if ($class->getType() && $class->getTypeId() == MetaClassType::CLASS_SPOOKED) {
         Assert::isFalse(count($class->getProperties()) > 1, 'spooked classes must have only identifier: ' . $class->getName());
         Assert::isTrue($class->getPattern() instanceof SpookedClassPattern || $class->getPattern() instanceof SpookedEnumerationPattern, 'spooked classes must use spooked patterns only: ' . $class->getName());
     }
     foreach ($class->getProperties() as $property) {
         if (!$property->getType()->isGeneric() && $property->getType() instanceof ObjectType && $property->getType()->getClass()->getPattern() instanceof ValueObjectPattern) {
             Assert::isTrue($property->isRequired(), 'optional value object is not supported:' . $property->getName() . ' @ ' . $class->getName());
             Assert::isTrue($property->getRelationId() == MetaRelation::ONE_TO_ONE, 'value objects must have OneToOne relation: ' . $property->getName() . ' @ ' . $class->getName());
         } elseif ($property->getFetchStrategyId() == FetchStrategy::LAZY && $property->getType()->isGeneric()) {
             throw new WrongArgumentException('lazy one-to-one is supported only for ' . 'non-generic object types ' . '(' . $property->getName() . ' @ ' . $class->getName() . ')');
         }
     }
     return $this;
 }
    public static function build(MetaClass $class)
    {
        $out = self::getHead();
        if ($type = $class->getType()) {
            $typeName = $type->toString() . ' ';
        } else {
            $typeName = null;
        }
        $interfaces = ' implements Prototyped';
        if ($class->getPattern()->daoExists() && !$class->getPattern() instanceof AbstractClassPattern) {
            $interfaces .= ', DAOConnected';
            $daoName = $class->getName() . 'DAO';
            $dao = <<<EOT
\t/**
\t * @return {$daoName}
\t**/
\tpublic static function dao()
\t{
\t\treturn Singleton::getInstance('{$daoName}');
\t}

EOT;
        } else {
            $dao = null;
        }
        $out .= <<<EOT
{$typeName}class {$class->getName()} extends Auto{$class->getName()}{$interfaces}
{
EOT;
        if (!$type || $type->getId() !== MetaClassType::CLASS_ABSTRACT) {
            $customCreate = null;
            if ($class->getFinalParent()->getPattern() instanceof InternalClassPattern) {
                $parent = $class;
                while ($parent = $parent->getParent()) {
                    $info = new ReflectionClass($parent->getName());
                    if ($info->hasMethod('create') && $info->getMethod('create')->getParameters() > 0) {
                        $customCreate = true;
                        break;
                    }
                }
            }
            if ($customCreate) {
                $creator = $info->getMethod('create');
                $declaration = array();
                foreach ($creator->getParameters() as $parameter) {
                    $declaration[] = '$' . $parameter->getName() . ' = ' . ($parameter->getDefaultValue() ? $parameter->getDefaultValue() : 'null');
                }
                $declaration = implode(', ', $declaration);
                $out .= <<<EOT

\t/**
\t * @return {$class->getName()}
\t**/
\tpublic static function create({$declaration})
\t{
\t\treturn new self({$declaration});
\t}
\t\t
EOT;
            } else {
                $out .= <<<EOT

\t/**
\t * @return {$class->getName()}
\t**/
\tpublic static function create()
\t{
\t\treturn new self;
\t}
\t\t
EOT;
            }
            $protoName = 'Proto' . $class->getName();
            $out .= <<<EOT

{$dao}
\t/**
\t * @return {$protoName}
\t**/
\tpublic static function proto()
\t{
\t\treturn Singleton::getInstance('{$protoName}');
\t}

EOT;
        }
        $out .= <<<EOT

\t// your brilliant stuff goes here
}

EOT;
        return $out . self::getHeel();
    }