private JMethod generateZclAttributeSetterImplementation(JCodeModel jModel, JDefinedClass jClusterClass, JClass jParentClass,
			ZclAttributeDescr zclAttributeDescriptor, boolean isServer) throws Exception {

		JMethod jMethod = generateZclAttributeSetterSignature(jModel, jClusterClass, jParentClass, zclAttributeDescriptor, true);

		JBlock jBlock = jMethod.body();

		JVar[] jParams = jMethod.listParams();
		JVar jContextParamVar = jParams[jParams.length - 1];
		JType jTypeZclFrame = jModel._ref(ZclFrame.class);

		// ATTENTION: use getPackage() otherwise it don't use import but
		// references the
		// type with a f
		JType type = getZclDataTypeJClass(jModel, jClusterClass.getPackage(), jParentClass, zclAttributeDescriptor.getTypeName(),
				zclAttributeDescriptor);

		if (checkIfAttached) {
			JVar jDeviceVar = jBlock.decl(zbDeviceClass, "device").init(JExpr.invoke("getZigBeeDevice"));

			jBlock._if(jDeviceVar.eq(JExpr._null()))._then()
					._throw(JExpr._new(jModel.ref(ApplianceException.class)).arg("Not attached"));
		}

		int attrId = zclAttributeDescriptor.getId();

		JVar jVarAttribute = null;
		JVar[] params = jMethod.listParams();
		for (int i = 0; i < params.length; i++) {
			if (params[i].name().equals(zclAttributeDescriptor.getName())) {
				jVarAttribute = params[i];
				break;
			}
		}

		if (jVarAttribute == null) {
			System.err.println("Internal ERROR");
		}

		JClass jClassZigBeeType = this.getZclDataTypeJClass(jModel, jClusterClass.getPackage(), jParentClass,
				zclAttributeDescriptor.getTypeName(), zclAttributeDescriptor);

		boolean oldVersion = false;

		JVar jVarAttrId = jBlock.decl(jModel._ref(int.class), "attrId").init(JExpr.lit(attrId));

		// payload size (attrId + dataType)
		JVar jVarSize = jBlock.decl(jModel._ref(int.class), "size").init(JExpr.lit(3));

		jBlock.assignPlus(jVarSize, jClassZigBeeType.staticInvoke("zclSize").arg(jVarAttribute));

		JVar jVarZclFrame = jBlock.decl(jModel._ref(IZclFrame.class), "zclFrame").init(
				JExpr._new(jTypeZclFrame).arg(JExpr.lit(0x00)).arg(jVarSize));

		// jBlock.directStatement("zclFrame.setSequence(sequence++);");
		// jBlock.invoke(jVarZclFrame, "setCommandId").arg(JExpr.lit(0x02));
		jBlock.invoke(jVarZclFrame, "appendUInt16").arg(jVarAttrId);
		jBlock.invoke(JExpr.ref("zclFrame"), "appendUInt8").arg(jClassZigBeeType.staticRef("ZCL_DATA_TYPE"));
		jBlock.staticInvoke(jClassZigBeeType, "zclSerialize").arg(jVarZclFrame).arg(JExpr.ref(zclAttributeDescriptor.getName()));

		if (oldVersion) {
			jBlock.directStatement("if (sync) {");

			JTryBlock jTryBlockInvoke = jBlock._try();
			jTryBlockInvoke.body().directStatement("	zclResponseFrame =  device.invoke(CLUSTER_ID, zclFrame);");

			jTryBlockInvoke._catch(jModel.ref(ZigBeeException.class)).body()
					._throw(JExpr._new(jModel.ref(ApplianceException.class)).arg(JExpr.direct("INVOKE_ERROR_MESSAGE")));

			if (isServer)
				jBlock.directStatement("	if (zclResponseFrame.isClientToServer())");
			else
				jBlock.directStatement("	if (zclResponseFrame.isServerToClient())");

			jBlock.directStatement("		throw new ApplianceException(BAD_DIRECTION_MESSAGE);");
			// jBlock._if(jZclResponseFrame.invoke("getCommandId").ne(JExpr.lit(0x05)))._then().directStatement(
			// "		throw new ApplianceException(BAD_RESPONSE_COMMAND_ID_MESSAGE + zclResponseFrame.getCommandId() + \"'\");");
			jBlock.directStatement("	return;");
			jBlock.directStatement("}");
			jBlock.directStatement("else {");
			jBlock.directStatement("	boolean res = device.post(CLUSTER_ID, zclFrame);");
			jBlock.directStatement("	if (!res) {");
			jBlock.directStatement("		throw new ApplianceException(POST_FAILED_MESSAGE);");
			jBlock.directStatement("	}");
			jBlock.directStatement("}");
		} else {
			jBlock.invoke("issueSet").arg(jClusterClass.staticRef("CLUSTER_ID")).arg(jVarZclFrame).arg(jVarAttrId)
					.arg(jContextParamVar);
		}
		return jMethod;
	}