public static function build(MetaClass $class)
    {
        $out = self::getHead();
        $out .= "abstract class Auto{$class->getName()}";
        $isNamed = false;
        if ($parent = $class->getParent()) {
            $out .= " extends {$parent->getName()}";
        } elseif ($class->getPattern() instanceof DictionaryClassPattern && $class->hasProperty('name')) {
            $out .= " extends NamedObject";
            $isNamed = true;
        } elseif (!$class->getPattern() instanceof ValueObjectPattern) {
            $out .= " extends IdentifiableObject";
        }
        if ($interfaces = $class->getInterfaces()) {
            $out .= ' implements ' . implode(', ', $interfaces);
        }
        $out .= "\n{\n";
        foreach ($class->getProperties() as $property) {
            if (!self::doPropertyBuild($class, $property, $isNamed)) {
                continue;
            }
            $out .= "protected \${$property->getName()} = " . "{$property->getType()->getDeclaration()};\n";
            if ($property->getFetchStrategyId() == FetchStrategy::LAZY) {
                $out .= "protected \${$property->getName()}Id = null;\n";
            }
        }
        $valueObjects = array();
        foreach ($class->getProperties() as $property) {
            if ($property->getType() instanceof ObjectType && !$property->getType()->isGeneric() && $property->getType()->getClass()->getPattern() instanceof ValueObjectPattern) {
                $valueObjects[$property->getName()] = $property->getType()->getClassName();
            }
        }
        if ($valueObjects) {
            $out .= <<<EOT

public function __construct()
{

EOT;
            foreach ($valueObjects as $propertyName => $className) {
                $out .= "\$this->{$propertyName} = new {$className}();\n";
            }
            $out .= "}\n";
        }
        foreach ($class->getProperties() as $property) {
            if (!self::doPropertyBuild($class, $property, $isNamed)) {
                continue;
            }
            $out .= $property->toMethods($class);
        }
        $out .= "}\n";
        $out .= self::getHeel();
        return $out;
    }
    protected static function buildPointers(MetaClass $class)
    {
        $out = null;
        if (!$class->getPattern() instanceof AbstractClassPattern) {
            if ($source = $class->getSourceLink()) {
                $out .= <<<EOT
\tprotected \$linkName =  '{$source}';
\t

EOT;
            }
            if ($class->getIdentifier()->getColumnName() !== 'id') {
                $out .= <<<EOT
public function getIdName()
{
\treturn '{$class->getIdentifier()->getColumnName()}';
}

EOT;
            }
            $out .= <<<EOT
public function getTable()
{
\treturn '{$class->getTableName()}';
}

public function getObjectName()
{
\treturn '{$class->getName()}';
}

public function getSequence()
{
\treturn '{$class->getTableName()}_id';
}
EOT;
        } elseif ($class->getWithInternalProperties()) {
            $out .= <<<EOT
// no get{Table,ObjectName,Sequence} for abstract class
EOT;
        }
        if ($liaisons = $class->getReferencingClasses()) {
            $uncachers = array();
            foreach ($liaisons as $className) {
                $uncachers[] = $className . '::dao()->uncacheLists();';
            }
            $uncachers = implode("\n", $uncachers);
            $out .= <<<EOT


public function uncacheLists()
{
{$uncachers}

return parent::uncacheLists();
}
EOT;
        }
        return $out;
    }
 /**
  * @return MetaConfiguration
  **/
 private function checkClassSanity(MetaClass $class, ReflectionClass $info)
 {
     switch ($class->getTypeId()) {
         case null:
             break;
         case MetaClassType::CLASS_ABSTRACT:
             Assert::isTrue($info->isAbstract(), 'class ' . $info->getName() . ' expected to be abstract');
             Assert::isTrue($class->getPattern() instanceof AbstractClassPattern, 'class ' . $info->getName() . ' must use AbstractClassPattern');
             break;
         case MetaClassType::CLASS_FINAL:
             Assert::isTrue($info->isFinal(), 'class ' . $info->getName() . ' expected to be final');
             break;
         case MetaClassType::CLASS_SPOOKED:
         default:
             Assert::isUnreachable();
             break;
     }
     if ($public = $info->getProperties(ReflectionProperty::IS_PUBLIC)) {
         Assert::isUnreachable($class->getName() . ' contains properties with evil visibility:' . "\n" . print_r($public, true));
     }
     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();
    }