private void generateSetter(
      BuilderModel model, boolean markGenerated, JType builder, BuilderPropertyModel property) {

    SourceTemplate setterMethod =
        newSourceTemplate()
            .var("p.name", property.getPropertyName())
            .var("p.type", property.getType().getFullName())
            .var("p.type_raw", property.getType().getFullNameRaw())
            .var("self.type", model.getBuilderSelfType())
            .var("self.getter", model.getBuilderSelfAccessor())
            .pl("public ${self.type} ${p.name}(final ${p.type} val){")
            .pl("	this.${p.name} = val;")
            .pl("	return ${self.getter};")
            .pl("}");

    addMethod(builder, setterMethod.asMethodNodeSnippet(), markGenerated);
  }
  private void generateField(boolean markGenerated, JType builder, BuilderPropertyModel property) {
    SourceTemplate field =
        newSourceTemplate()
            .var("p.name", property.getPropertyName())
            .var("p.type", property.getType().getFullName())
            .pl("private ${p.type} ${p.name};");

    addField(builder, field.asFieldNodeSnippet(), markGenerated);
  }
  private void generateAllArgCtor(JType beanType, BuilderModel model) {
    if (!beanType.isAbstract()) {
      SourceTemplate beanCtor =
          newSourceTemplate()
              .var("b.name", model.getPojoType().getSimpleNameRaw())
              .pl("private ${b.name} (");

      boolean comma = false;
      // args
      for (BuilderPropertyModel property : model.getProperties()) {
        if (property.isReadOnly()) {
          continue;
        }
        if (comma) {
          beanCtor.p(",");
        }
        if (model.isMarkCtorArgsAsProperties()) {
          beanCtor.p(
              "@" + Property.class.getName() + "(name=\"" + property.getPropertyName() + "\") ");
        }
        beanCtor.p(property.getType().getFullName() + " " + property.getPropertyName());
        comma = true;
      }

      beanCtor.pl("){");
      // field assignments
      for (BuilderPropertyModel property : model.getProperties()) {
        if (property.isReadOnly()) {
          continue;
        }
        // TODO:figure out if we can set field directly, via setter, or via ctor args
        // for now assume a setter
        if (property.isFromSuperClass()) {
          beanCtor.pl(property.getPropertySetterName() + "(" + property.getPropertyName() + ");");
        } else {
          beanCtor.pl("this." + property.getFieldName() + "=" + property.getPropertyName() + ";");
        }
        comma = true;
      }
      beanCtor.pl("}");
      addMethod(beanType, beanCtor.asConstructorNodeSnippet(), model.isMarkGenerated());
    }
  }
  private void generateMapAddRemove(JType bean, BuilderModel model, BuilderPropertyModel property) {
    if (property.getType().isMap() && model.isGenerateAddRemoveMethodsForIndexedProperties()) {
      SourceTemplate add =
          newSourceTemplate()
              .var("p.name", property.getPropertyName())
              .var("p.addName", property.getPropertyAddName())
              .var("p.type", property.getType().getObjectTypeFullName())
              .var("p.newType", property.getPropertyConcreteType())
              .var("p.genericPart", property.getType().getGenericPartOrEmpty())
              .var("p.keyType", property.getType().getIndexedKeyTypeNameOrNull())
              .var("p.valueType", property.getType().getIndexedValueTypeNameOrNull())
              .var("self.type", model.getBuilderSelfType())
              .var("self.getter", model.getBuilderSelfAccessor())
              .pl(
                  "public ${self.type} ${p.addName}(final ${p.keyType} key,final ${p.valueType} val){")
              .pl(
                  "	if(this.${p.name} == null){ this.${p.name} = new ${p.newType}${p.genericPart}(); }")
              .pl("	this.${p.name}.put(key, val);")
              .pl("	return ${self.getter};")
              .pl("}");

      addMethod(bean, add.asMethodNodeSnippet(), model.isMarkGenerated());

      SourceTemplate remove =
          newSourceTemplate()
              .var("p.name", property.getPropertyName())
              .var("p.removeName", property.getPropertyRemoveName())
              .var("p.type", property.getType().getObjectTypeFullName())
              .var("p.newType", property.getPropertyConcreteType())
              .var("p.keyType", property.getType().getIndexedKeyTypeNameOrNull())
              .var("self.type", model.getBuilderSelfType())
              .var("self.getter", model.getBuilderSelfAccessor())
              .pl("public ${self.type} ${p.removeName}(final ${p.keyType} key){")
              .pl("	if(this.${p.name} != null){ ")
              .pl("		this.${p.name}.remove(key);")
              .pl("	}")
              .pl("	return ${self.getter};")
              .pl("}");

      addMethod(bean, remove.asMethodNodeSnippet(), model.isMarkGenerated());
    }
  }