class CustomResourceDefinitionVersionDecorator<T> extends Decorator<VisitableBuilder> {

  protected static final String ANY = null;

  private final String name;
  private final String version;

  private final CustomResourceDefinitionVersionVisitor versionSelector = new CustomResourceDefinitionVersionVisitor();
  private final VersionVisitor versionVisitor = new VersionVisitor();

  public CustomResourceDefinitionVersionDecorator(String name, String version) {
    this.name = name;
    this.version = version;
  }

  public String getName() {
    return this.name;
  }

  public String getVersion() {
    return this.version;
  }

  @Override
  public void visit(VisitableBuilder builder) {<FILL_FUNCTION_BODY>}

  public abstract void andThenVisit(T version);

  private class CustomResourceDefinitionVersionVisitor extends TypedVisitor<CustomResourceDefinitionVersionBuilder> {

    @Override
    public void visit(CustomResourceDefinitionVersionBuilder builder) {
      if (Utils.isNullOrEmpty(version) || builder.getName().equals(version)) {
        builder.accept(versionVisitor);
      }
    }
  }

  private class VersionVisitor extends TypedVisitor<T> {

    @Override
    public void visit(T version) {
      andThenVisit(version);
    }

    public Class<T> getType() {
      return (Class) Generics
          .getTypeArguments(CustomResourceDefinitionVersionDecorator.class,
              CustomResourceDefinitionVersionDecorator.this.getClass())
          .get(0);
    }
  }

  @Override
  public Class<? extends Decorator>[] after() {
    return new Class[] {
        AddCustomResourceDefinitionResourceDecorator.class,
        AddCustomResourceDefinitionVersionDecorator.class };
  }

  @Override
  public Class<? extends Decorator>[] before() {
    return new Class[] {};
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((name == null) ? 0 : name.hashCode());
    result = prime * result + ((version == null) ? 0 : version.hashCode());
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj)
      return true;
    if (obj == null)
      return false;
    if (getClass() != obj.getClass())
      return false;
    CustomResourceDefinitionVersionDecorator other = (CustomResourceDefinitionVersionDecorator) obj;
    if (name == null) {
      if (other.name != null)
        return false;
    } else if (!name.equals(other.name))
      return false;
    if (version == null) {
      if (other.version != null)
        return false;
    } else if (!version.equals(other.version))
      return false;
    return true;
  }
}

    Optional<ObjectMeta> objectMeta = getMetadata(builder);
    if (!objectMeta.isPresent()) {
      return;
    }
    if (Utils.isNullOrEmpty(name) || objectMeta.map(ObjectMeta::getName).filter(s -> s.equals(name)).isPresent()) {
      builder.accept(versionSelector);
    }
  
<methods>public non-sealed void <init>() ,public Class<? extends Decorator#RAW>[] after() ,public Class<? extends Decorator#RAW>[] before() ,public int compareTo(Decorator#RAW) <variables>