protected void generateClassDefinition(Writer writer, AnnotationMirror annotation, ClassDefinition definition, String className, Element element) throws IOException {
        Elements elementUtils = processingEnv.getElementUtils();

        String packageName = resolvePackageName(annotation, definition);
        String generationTime = String.format("%1$tFT%1$tH:%1$tM:%1$tS.%1$tL%1$tz", new Date()); //%1$tY%1$tm%1$td-%1$tH%1$tk%1$tS-%1$tN%1$tz

        writer.append("package ").append(packageName).append(";\n\n");
        writer.append("@javax.annotation.Generated(value = \"" + this.getClass().getName() + "\", date = \"" + generationTime + "\")\n");
        writer.append("public ").append(isAbstract(annotation, definition) ? "abstract " : "").append("class ").append(className);

        boolean extended = false;
        boolean implemented = false;
        
        Map<? extends ExecutableElement, ? extends AnnotationValue> annotationValueMap = elementUtils.getElementValuesWithDefaults(annotation);
        String superClassName = getSuperClassValue(annotationValueMap);
        if(!superClassName.isEmpty()) {
            writer.append(" extends ").append(superClassName);
            extended = true;
        }
        
        switch(definition.getElementType()) {
            case CLASS:
                extended = true;
                break;
            case INTERFACE:
                implemented = true;
                break;
        }

        writer.append(" ").append(definition.getElementType().getExtendString()).append(" ").append(definition.getPackage() + "." + definition.getClassName());

        boolean isSerializable = isSerializable(annotation);
        if(isSerializable) {
            writer.append(getBindString(implemented)).append("java.io.Serializable");
            implemented = true;
        }

        if(isCloneable(annotation)) {
            writer.append(getBindString(implemented)).append("java.lang.Cloneable");
            implemented = true;
        }

        writer.append(" {\n");

        if(isSerializable) {
            AnnotationValue serialVersionValue = getValueOfAnnotation(annotationValueMap, SERIAL_VERSION);
            Long version = (Long)serialVersionValue.getValue();
            writer.append(indent(1)).append("private static final long serialVersionUID = ").append(version.toString()).append("L;\n");
        }
    }