class EnumConstantImpl implements EnumConstant {

    private Enum parent;
	private String name;
    private Javadoc javadoc;
    private final List<Import> imports;
    private final List<ClassOrInterface<?>> classes;
    private final List<Initializer> initializers;
    private final List<Method> methods;
    private final List<Field> fields;
	private final List<Value<?>> values;
	private final List<AnnotationUsage> annotations;

    /**
     * Initializes this enum constant using a name.
     * <p>
     * <b>Warning!</b> This class should not be instantiated directly but using 
     * the {@link EnumConstant#of(java.lang.String)} method!
     * 
     * @param name  the name
     */
	public EnumConstantImpl(String name) {
		this.name	      = requireNonNull(name);
		this.imports      = new ArrayList<>();
		this.classes      = new ArrayList<>();
		this.initializers = new ArrayList<>();
		this.methods      = new ArrayList<>();
		this.fields       = new ArrayList<>();
		this.values       = new ArrayList<>();
		this.annotations  = new ArrayList<>();
	}
	
    /**
     * Copy constructor.
     * 
     * @param prototype  the prototype 
     */
	protected EnumConstantImpl(EnumConstant prototype) {
	    name	     = requireNonNull(prototype).getName();
        javadoc      = prototype.getJavadoc().orElse(null);
		imports	     = Copier.copy(prototype.getImports());
		classes	     = Copier.copy(prototype.getClasses(), ClassOrInterface::copy);
		initializers = Copier.copy(prototype.getInitializers(), HasCopy::copy);
		methods	     = Copier.copy(prototype.getMethods(), HasCopy::copy);
		fields	     = Copier.copy(prototype.getFields(), HasCopy::copy);
		values	     = Copier.copy(prototype.getValues(), HasCopy::copy);
        annotations  = Copier.copy(prototype.getAnnotations(), HasCopy::copy);
	}

    @Override
    public EnumConstant setParent(Enum parent) {
        this.parent = parent;
        return this;
    }

    @Override
    public Optional<Enum> getParent() {
        return Optional.ofNullable(parent);
    }

    @Override
    public List<Import> getImports() {
        return imports;
    }

    @Override
	public EnumConstant setName(String name) {
		this.name = requireNonNull(name);
		return this;
	}

	@Override
	public String getName() {
		return name;
	}

    @Override
	public List<Value<?>> getValues() {
		return values;
	}
    
    @Override
    public EnumConstant set(Javadoc doc) {
        this.javadoc = doc.setParent(this);
        return this;
    }

    @Override
    public Optional<Javadoc> getJavadoc() {
        return Optional.ofNullable(javadoc);
    }

    @Override
    public List<ClassOrInterface<?>> getClasses() {
        return classes;
    }

    @Override
    public List<Initializer> getInitializers() {
        return initializers;
    }

    @Override
    public List<Method> getMethods() {
        return methods;
    }

    @Override
    public List<Field> getFields() {
        return fields;
    }

    @Override
    public List<AnnotationUsage> getAnnotations() {
        return annotations;
    }

    @Override
	public EnumConstantImpl copy() {
		return new EnumConstantImpl(this);
	}

    @Override
    public boolean equals(Object o) {<FILL_FUNCTION_BODY>}

    @Override
    public int hashCode() {
        return Objects.hash(name, javadoc, imports, classes, initializers, methods, fields, values, annotations)
                + HashUtil.identityHashForParent(this);
    }
}

        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        final EnumConstantImpl that = (EnumConstantImpl) o;
        return Objects.equals(parent, that.parent) &&
                Objects.equals(name, that.name) &&
                Objects.equals(javadoc, that.javadoc) &&
                Objects.equals(imports, that.imports) &&
                Objects.equals(classes, that.classes) &&
                Objects.equals(initializers, that.initializers) &&
                Objects.equals(methods, that.methods) &&
                Objects.equals(fields, that.fields) &&
                Objects.equals(values, that.values) &&
                Objects.equals(annotations, that.annotations);
    
<no_super_class>