text:
package gov.nih.nci.cananolab.restful.sample;

import gov.nih.nci.cananolab.domain.common.File;
import gov.nih.nci.cananolab.domain.common.Keyword;
import gov.nih.nci.cananolab.dto.common.ColumnHeader;
import gov.nih.nci.cananolab.dto.common.ExperimentConfigBean;
import gov.nih.nci.cananolab.dto.common.FileBean;
import gov.nih.nci.cananolab.dto.common.FindingBean;
import gov.nih.nci.cananolab.dto.common.ProtocolBean;
import gov.nih.nci.cananolab.dto.common.Row;
import gov.nih.nci.cananolab.dto.common.TableCell;
import gov.nih.nci.cananolab.dto.particle.SampleBean;
import gov.nih.nci.cananolab.dto.particle.characterization.CharacterizationBean;
import gov.nih.nci.cananolab.dto.particle.characterization.CharacterizationSummaryViewBean;
import gov.nih.nci.cananolab.restful.core.BaseAnnotationBO;
import gov.nih.nci.cananolab.restful.protocol.InitProtocolSetup;
import gov.nih.nci.cananolab.restful.util.PropertyUtil;
import gov.nih.nci.cananolab.restful.view.SimpleCharacterizationSummaryViewBean;
import gov.nih.nci.cananolab.restful.view.SimpleCharacterizationUnitBean;
import gov.nih.nci.cananolab.restful.view.SimpleCharacterizationsByTypeBean;
import gov.nih.nci.cananolab.restful.view.edit.SimpleCell;
import gov.nih.nci.cananolab.restful.view.edit.SimpleCharacterizationEditBean;
import gov.nih.nci.cananolab.restful.view.edit.SimpleCharacterizationSummaryEditBean;
import gov.nih.nci.cananolab.restful.view.edit.SimpleExperimentBean;
import gov.nih.nci.cananolab.restful.view.edit.SimpleFileBean;
import gov.nih.nci.cananolab.restful.view.edit.SimpleFindingBean;
import gov.nih.nci.cananolab.restful.view.edit.SimpleRowBean;
import gov.nih.nci.cananolab.security.enums.SecureClassesEnum;
import gov.nih.nci.cananolab.security.service.SpringSecurityAclService;
import gov.nih.nci.cananolab.security.utils.SpringSecurityUtil;
import gov.nih.nci.cananolab.service.curation.CurationService;
import gov.nih.nci.cananolab.service.protocol.ProtocolService;
import gov.nih.nci.cananolab.service.sample.CharacterizationService;
import gov.nih.nci.cananolab.service.sample.SampleService;
import gov.nih.nci.cananolab.service.sample.impl.CharacterizationExporter;
import gov.nih.nci.cananolab.util.Constants;
import gov.nih.nci.cananolab.util.DateUtils;
import gov.nih.nci.cananolab.util.ExportUtils;
import gov.nih.nci.cananolab.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * Base action for characterization actions
 *
 * @author pansu
 */
@Transactional(readOnly=false, propagation=Propagation.REQUIRED)
@Component("characterizationBO")
public class CharacterizationBO extends BaseAnnotationBO {

	private Logger logger = Logger.getLogger(CharacterizationBO.class);

	@Autowired
	private CharacterizationService characterizationService;

	@Autowired
	private CurationService curationServiceDAO;

	@Autowired
	private SampleService sampleService;

	@Autowired
	private SpringSecurityAclService springSecurityAclService;

	@Autowired
	private UserDetailsService userDetailsService;

	@Autowired
	private ProtocolService protocolService;

	/**
	 * Add or update a characterization to database
	 *
	 * Upon success, go back to characterizaiton summary edit page
	 *
	 * @param request
	 * @param simpleEdit
	 * @return
	 * @throws Exception
	 */
	public SimpleCharacterizationSummaryEditBean submitOrUpdate(HttpServletRequest request,
			SimpleCharacterizationEditBean simpleEdit)
			throws Exception {

		CharacterizationBean charBean = (CharacterizationBean)request.getSession().getAttribute("theChar");

		simpleEdit.getErrors().clear();
		simpleEdit.getMessages().clear();

		charBean = simpleEdit.transferToCharacterizationBean(charBean);
		if (simpleEdit.getCharId() == 0)
			simpleEdit.setSubmitNewChar(true);

		List<String> errs = new ArrayList<String>();
		if (!validateInputs(request, charBean, errs)) {
			SimpleCharacterizationSummaryEditBean emptyView = new SimpleCharacterizationSummaryEditBean();
			emptyView.setErrors(errs);
			return emptyView;
		}

		this.saveCharacterization(request, charBean, simpleEdit);
		simpleEdit.getMessages().add(PropertyUtil.getPropertyReplacingToken("sample", "message.addCharacterization", "0",
				charBean.getCharacterizationName()));

		InitCharacterizationSetup.getInstance() //save "others" to db
			.persistCharacterizationDropdowns(request, charBean);

		SimpleCharacterizationSummaryEditBean success = new SimpleCharacterizationSummaryEditBean();
		success.getMessages().add("The characterization has been saved successfully");
		return success;
	}

//	public ActionForward input(ActionMapping mapping, ActionForm form,
//			HttpServletRequest request, HttpServletResponse response)
//			throws Exception {
//		DynaValidatorForm theForm = (DynaValidatorForm) form;
//		CharacterizationBean charBean = (CharacterizationBean) theForm
//				.get("achar");
//		charBean.updateEmptyFieldsToNull();
//		this.checkOpenForms(charBean, theForm, request);
//
//		// Save uploaded data in session to avoid asking user to upload again.
//		FileBean theFile = charBean.getTheFinding().getTheFile();
//		escapeXmlForFileUri(theFile);
//		String charName = StringUtils.getOneWordLowerCaseFirstLetter(charBean
//				.getCharacterizationName());
//		preserveUploadedFile(request, theFile, charName);
//
//		return mapping.findForward("inputForm");
//	}

	/**
	 * Set up the input form for adding new characterization
	 *
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public SimpleCharacterizationEditBean setupNew(HttpServletRequest request, String sampleId, String charType) throws Exception
	{
		if (StringUtils.isEmpty(sampleId))
			throw new Exception("Sample id is empty");

		if (StringUtils.isEmpty(charType))
			throw new Exception("Characterization type is empty");

		//This method sets tons of lookups. Need to see what's needed and what's not
		//setupInputForm(request, sampleId, charType);

		CharacterizationBean charBean = new CharacterizationBean();
		charBean.setCharacterizationType(charType);

		//this.checkOpenForms(charBean, theForm, request);
		// clear copy to otherSamples
//		clearCopy(theForm);
//		return mapping.findForward("inputForm");
		SimpleCharacterizationEditBean editBean = new SimpleCharacterizationEditBean();
		editBean.transferFromCharacterizationBean(request, charBean, sampleId, sampleService, characterizationService, protocolService, springSecurityAclService);

		request.getSession().setAttribute("theEditChar", editBean);
		request.getSession().setAttribute("theChar", charBean);
		return editBean;
	}

	/**
	 * Set up drop-downs need for the input form
	 *
	 * @param request
	 * @param theForm
	 * @throws Exception
	 */
	private void setupInputForm(HttpServletRequest request, String sampleId, String charType) throws Exception
	{
		if (StringUtils.isEmpty(sampleId))
			throw new Exception("Sample id is invalid");

		if (!StringUtils.isEmpty(charType))
			protocolService.getProtocolsByChar(request, charType);
		InitCharacterizationSetup.getInstance().setPOCDropdown(request, sampleId, sampleService);
//		InitCharacterizationSetup.getInstance().setCharacterizationDropdowns(
//				request);

		// set up other samples with the same primary point of contact
		InitSampleSetup.getInstance().getOtherSampleNames(request, sampleId, sampleService);
	}

	/**
	 * Set up the input form for editing existing characterization
	 *
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public SimpleCharacterizationEditBean setupUpdate(HttpServletRequest request, String sampleId, String charId, String charClassName, String charType)
			throws Exception
	{
		charId = super.validateCharId(charId);

		CharacterizationBean charBean = characterizationService.findCharacterizationById(charId);

//
//		// TODO: Find out usage of "charNameDatumNames", not used in any JSPs.
//		InitCharacterizationSetup.getInstance().getDatumNamesByCharName(
//				request, charBean.getCharacterizationType(),
//				charBean.getCharacterizationName(), charBean.getAssayType());
//			charBean.getCharacterizationName(), charBean.getAssayType());

		//SY: new
		request.getSession().setAttribute("theChar", charBean);
		logger.debug("Setting theChar in session: " + request.getSession().getId());;

		SimpleCharacterizationEditBean editBean = new SimpleCharacterizationEditBean();
		editBean.transferFromCharacterizationBean(request, charBean, sampleId, sampleService, characterizationService, protocolService, springSecurityAclService);
		request.getSession().setAttribute("theEditChar", editBean);
		return editBean;
	}

//	private void clearCopy(DynaValidatorForm theForm) {
//		theForm.set("otherSamples", new String[0]);
//		theForm.set("copyData", false);
//	}

	/**
	 * Setup, prepare and save characterization.
	 *
	 * @param request
	 * @param theForm
	 * @param charBean
	 * @throws Exception
	 */
	private void saveCharacterization(HttpServletRequest request,
			CharacterizationBean charBean, SimpleCharacterizationEditBean simpleEdit)
			throws Exception
	{
		SampleBean sampleBean = setupSampleById(String.valueOf(simpleEdit.getParentSampleId()), request);

		charBean.setupDomain(SpringSecurityUtil.getLoggedInUserName());

		if (charBean.getDomainChar().getDate() == null && simpleEdit.getCharacterizationDate() != null)
			charBean.getDomainChar().setDate(simpleEdit.getCharacterizationDate());

		Boolean newChar = true;
		if (charBean.getDomainChar().getId() != null) {
			newChar = false;
		}
		logger.debug("Saving new char? " + newChar);

		characterizationService.saveCharacterization(sampleBean, charBean);
		// retract from public if updating an existing public record and not curator
		if (!newChar && !SpringSecurityUtil.getPrincipal().isCurator() &&
			springSecurityAclService.checkObjectPublic(sampleBean.getDomain().getId(), SecureClassesEnum.SAMPLE.getClazz()))
		{
			retractFromPublic(request, sampleBean.getDomain().getId(), sampleBean.getDomain().getName(), "sample", SecureClassesEnum.SAMPLE.getClazz());

			simpleEdit.getErrors().add(PropertyUtil.getProperty("sample", "message.updateSample.retractFromPublic"));
		}

		// save to other samples (only when user click [Submit] button.)
		if (simpleEdit.getSelectedOtherSampleNames().size()>0) {
			SampleBean[] otherSampleBeans = prepareCopy(request, simpleEdit.getSelectedOtherSampleNames(), sampleBean);
			if (otherSampleBeans != null) {
				characterizationService.copyAndSaveCharacterization(charBean, sampleBean,
						otherSampleBeans, simpleEdit.isCopyToOtherSamples()); //field should be renamed to copyDeepData
			}

			simpleEdit.setSubmitNewChar(false);
		}

		sampleBean = setupSampleById(String.valueOf(simpleEdit.getParentSampleId()), request);
		request.setAttribute("sampleId", sampleBean.getDomain().getId().toString());
		logger.debug("Done saving characterization: " + charBean.getDomainChar().getId());
	}

	private void deleteCharacterization(HttpServletRequest request, CharacterizationBean charBean, String createdBy) throws Exception
	{
		charBean.setupDomain(createdBy);
		characterizationService.deleteCharacterization(charBean.getDomainChar());
		characterizationService.removeAccesses(charBean.getDomainChar());
	}

	public SimpleCharacterizationSummaryEditBean delete(HttpServletRequest request, SimpleCharacterizationEditBean editBean)
			throws Exception
	{
		CharacterizationBean charBean = (CharacterizationBean)request.getSession().getAttribute("theChar");
		if (charBean == null)
			throw new Exception("No characterization bean in session. Unable to proceed with delete");

		Long charId = charBean.getDomainChar().getId();
		if (charId == null)
			throw new Exception("Characterization bean in session has null id. Unable to proceed with delete");

		if (charId.longValue() != editBean.getCharId())
			throw new Exception("Characterization id in session doesn't match input char id. Unable to proceed with delete");

		deleteCharacterization(request, charBean, SpringSecurityUtil.getLoggedInUserName());

		SimpleCharacterizationSummaryEditBean summaryEdit = new SimpleCharacterizationSummaryEditBean();
		summaryEdit.getMessages().add(PropertyUtil.getProperty("sample", "message.deleteCharacterization"));

		return this.summaryEdit(String.valueOf(editBean.getParentSampleId()), request, summaryEdit);
	}

	/**
	 * summaryEdit() handles Edit request for Characterization Summary view.
	 *
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return ActionForward
	 * @throws Exception
	 */
	public SimpleCharacterizationSummaryEditBean summaryEdit(String sampleId,
			HttpServletRequest request, SimpleCharacterizationSummaryEditBean editBean)
			throws Exception {
		// Prepare data.
		CharacterizationSummaryViewBean sumBean = this.prepareSummary(sampleId, request);

		if (editBean == null)
			editBean = new SimpleCharacterizationSummaryEditBean();

		List<SimpleCharacterizationsByTypeBean> finalBeans = editBean.transferData(request, sumBean, sampleId);
		return editBean;
	}

	/**
	 * summaryView() handles View request for Characterization Summary report.
	 *
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return ActionForward
	 * @throws Exception
	 *             if error occurred.
	 */
	public CharacterizationSummaryViewBean summaryView(String sampleId,
			HttpServletRequest request)
			throws Exception {

		if (sampleId == null || sampleId.length() == 0)
			throw new Exception("sampleId can't be null or empty");

		CharacterizationSummaryViewBean viewBean = prepareSummary(sampleId, request);
		List<String> charTypes = prepareCharacterizationTypes(request);
		//setSummaryTab(request, charTypes.size());
		return viewBean;
	}

//	public ActionForward setupView(ActionMapping mapping, ActionForm form,
//			HttpServletRequest request, HttpServletResponse response)
//			throws Exception {

		//TODO
//		DynaValidatorForm theForm = (DynaValidatorForm) form;
//		CharacterizationService service = this.setServicesInSession(request);
//		String charId = super.validateId(request, "charId");
//		setupSample(theForm, request);
//		CharacterizationBean charBean = service
//				.findCharacterizationById(charId);
//		request.setAttribute("charBean", charBean);
//		return mapping.findForward("singleSummaryView");
//	}

	/**
	 * Shared function for summaryView(), summaryPrint() and summaryEdit().
	 * Prepare CharacterizationBean based on Sample Id.
	 *
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return ActionForward
	 * @throws Exception
	 */
	private CharacterizationSummaryViewBean prepareSummary(String sampleId, HttpServletRequest request)
			throws Exception {
		// Remove previous result from session.
		request.getSession().removeAttribute("characterizationSummaryView");

		//DynaValidatorForm theForm = (DynaValidatorForm) form;
		//String sampleId = form.getSampleId();  //.getString(SampleConstants.SAMPLE_ID);

		List<CharacterizationBean> charBeans = characterizationService.findCharacterizationsBySampleId(sampleId);
		CharacterizationSummaryViewBean summaryView = new CharacterizationSummaryViewBean(charBeans);

		request.getSession().setAttribute("characterizationSummaryView", summaryView);

		// Save sample bean in session for sample name in export/print.
		//request.getSession().setAttribute("theSample", sampleBean);

		return summaryView;
	}

	/**
	 * Shared function for summaryView() and summaryPrint(). Keep submitted
	 * characterization types in the correct display order. Should be called
	 * after calling prepareSummary(), to avoid session timeout issue.
	 *
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return ActionForward
	 * @throws Exception
	 */
	private List<String> prepareCharacterizationTypes(HttpServletRequest request) throws Exception {

		CharacterizationSummaryViewBean summaryView = (CharacterizationSummaryViewBean) request
				.getSession().getAttribute("characterizationSummaryView");
		// Keep submitted characterization types in the correct display order
		// prepare characterization tabs and forward to appropriate tab
		List<String> allCharacterizationTypes = InitCharacterizationSetup
				.getInstance().getCharacterizationTypes(request);
		Set<String> foundTypes = summaryView.getCharacterizationTypes();
		List<String> characterizationTypes = new ArrayList<String>();
		for (String charType : allCharacterizationTypes) {
			if (foundTypes.contains(charType)
					&& !characterizationTypes.contains(charType)) {
				characterizationTypes.add(charType);
			}
		}
		// other types that are not in allCharacterizationTypes, e.g. other
		// types from grid search
		for (String type : foundTypes) {
			if (!characterizationTypes.contains(type)) {
				characterizationTypes.add(type);
			}
		}
		request.setAttribute("characterizationTypes", characterizationTypes);
		return characterizationTypes;
	}

	/**
	 * summaryPrint() handles Print request for Characterization Summary report.
	 *
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return ActionForward
	 * @throws Exception
	 */
	public CharacterizationSummaryViewBean summaryPrint(String sampleId,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		CharacterizationSummaryViewBean charSummaryBean = (CharacterizationSummaryViewBean) request
				.getSession().getAttribute("characterizationSummaryView");
		if (charSummaryBean == null) {
			// Retrieve data again when session timeout.
			this.prepareSummary(sampleId, request);
			charSummaryBean = (CharacterizationSummaryViewBean) request
					.getSession().getAttribute("characterizationSummaryView");
		}

		//TODO: w
		List<String> charTypes = prepareCharacterizationTypes(request);

		this.filterType(request, "all", charTypes); // Filter out un-selected types.

		// Marker that indicates page is for printing only, hide tabs/links.
		request.setAttribute("printView", Boolean.TRUE);

		//return mapping.findForward("summaryPrintView");
		return charSummaryBean;
	}

	/**
	 * Export Characterization Summary report.
	 *
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return ActionForward
	 * @throws Exception
	 */
	public String summaryExport(String sampleId, String type,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {

		if (sampleId == null || sampleId.length() == 0)
			return "Sample Id can't be null or empty";

		if (type == null)
			type = "all";

		SampleBean sampleBean = (SampleBean) request.getSession().getAttribute(
				"theSample");
		CharacterizationSummaryViewBean charSummaryBean = (CharacterizationSummaryViewBean) request
				.getSession().getAttribute("characterizationSummaryView");
		if (sampleBean == null || charSummaryBean == null) {
			// Prepare data.
			this.prepareSummary(sampleId, request);
			sampleBean = (SampleBean) request.getSession().getAttribute(
					"theSample");
			charSummaryBean = (CharacterizationSummaryViewBean) request
					.getSession().getAttribute("characterizationSummaryView");
		}
		List<String> charTypes = prepareCharacterizationTypes(request);
		List<String> filteredCharTypes = this.filterType(request, type, charTypes);

		//String type = "all"; //request.getParameter("type");
		// per app scan
		if (!StringUtils.xssValidate(type)) {
			type = "";
		}
		String sampleName = sampleBean.getDomain().getName();
		String fileName = ExportUtils.getExportFileName(sampleName,
				"CharacterizationSummaryView", type);
		ExportUtils.prepareReponseForExcel(response, fileName);

		StringBuilder sb = getDownloadUrl(request);
		CharacterizationExporter.exportSummary(filteredCharTypes,
				charSummaryBean, sb.toString(), response.getOutputStream());

		return "success";
	}

	public SimpleCharacterizationEditBean saveExperimentConfig(HttpServletRequest request,
			SimpleCharacterizationEditBean charEditBean) throws Exception
	{
		logger.debug("Start saving experiment confg");

		//editBean's charId could be null, indicating new char
		CharacterizationBean achar = (CharacterizationBean) request.getSession().getAttribute("theChar");
//		SimpleCharacterizationEditBean editBean =
//				(SimpleCharacterizationEditBean) request.getSession().getAttribute("theEditChar");

		SimpleExperimentBean simpleExpConfig = charEditBean.getDirtyExperimentBean();

		ExperimentConfigBean configBean = this.findMatchExperimentConfig(achar, simpleExpConfig);

		simpleExpConfig.transferToExperimentConfigBean(configBean);

		configBean.setupDomain(SpringSecurityUtil.getLoggedInUserName());
		logger.debug("Call saveExperimentConfig");
		String sampleId = (String) request.getSession().getAttribute("sampleId");
		characterizationService.saveExperimentConfig(sampleId, configBean);
		logger.debug("Save exp config complete");
		achar.addExperimentConfig(configBean);

		//transfer other data fields of the char
		achar = charEditBean.transferToCharacterizationBean(achar);

		// This is to validate characterization data fields
		if (!validateInputs(request, achar, charEditBean.getMessages())) {
			return charEditBean;
		}

		this.saveCharacterization(request, achar, charEditBean);
		logger.debug("Save char complete");
		characterizationService.assignAccesses(achar.getDomainChar(), configBean.getDomain());

		//TODO:
		//this.checkOpenForms(achar, theForm, request);
		InitCharacterizationSetup.getInstance().persistCharacterizationDropdowns(request, achar);

		// return to setupUpdate to retrieve the data matrix in the correct
		// form from database
		// after saving to database.
		request.setAttribute("charId", achar.getDomainChar().getId().toString());
		request.setAttribute("charType", achar.getCharacterizationType());

		return setupUpdate(request, String.valueOf(charEditBean.getParentSampleId()), achar.getDomainChar().getId().toString(),
				achar.getClassName(), achar.getCharacterizationType());

	}

//	public ActionForward getFinding(ActionMapping mapping, ActionForm form,
//			HttpServletRequest request, HttpServletResponse response)
//			throws Exception {
//		DynaValidatorForm theForm = (DynaValidatorForm) form;
//		String theFindingId = request.getParameter("findingId");
//		CharacterizationService service = this.setServicesInSession(request);
//		FindingBean findingBean = service.findFindingById(theFindingId);
//		CharacterizationBean achar = (CharacterizationBean) theForm
//				.get("achar");
//		achar.setTheFinding(findingBean);
//
//		request.setAttribute("anchor", "submitFinding");
//		this.checkOpenForms(achar, theForm, request);
//
//		// Feature request [26487] Deeper Edit Links.
//		if (findingBean.getFiles().size() == 1) {
//			request.setAttribute("onloadJavascript", "setTheFile(0)");
//		}
//		request.setAttribute("disableOuterButtons", true);
//		// remove columnHeaders stored in the session;
//		request.getSession().removeAttribute("columnHeaders");
//		return mapping.findForward("inputForm");
//	}

//	public ActionForward resetFinding(ActionMapping mapping, ActionForm form,
//			HttpServletRequest request, HttpServletResponse response)
//			throws Exception {
//		DynaValidatorForm theForm = (DynaValidatorForm) form;
//		FindingBean theFinding = new FindingBean();
//		// theFinding.setNumberOfColumns(1);
//		// theFinding.setNumberOfRows(1);
//		// theFinding.updateMatrix(theFinding.getNumberOfColumns(), theFinding
//		// .getNumberOfRows());
//		CharacterizationBean achar = (CharacterizationBean) theForm
//				.get("achar");
//		achar.setTheFinding(theFinding);
//		request.setAttribute("anchor", "submitFinding");
//		this.checkOpenForms(achar, theForm, request);
//		request.setAttribute("disableOuterButtons", true);
//		request.getSession().removeAttribute("columnHeaders");
//		return mapping.findForward("inputForm");

//		return null;
//	}

	public SimpleCharacterizationEditBean saveFinding(HttpServletRequest request,
			SimpleCharacterizationEditBean editBean
			/*SimpleFindingBean simpleFinding*/)
			throws Exception {

		CharacterizationBean achar = (CharacterizationBean) request.getSession().getAttribute("theChar");
//		SimpleCharacterizationEditBean editBean =
//				(SimpleCharacterizationEditBean) request.getSession().getAttribute("theEditChar");

		SimpleFindingBean simpleFinding = editBean.getDirtyFindingBean();

		if (simpleFinding == null)
			throw new Exception("Can't find dirty finding object"); //temp

		FindingBean findingBean = this.findMatchFindingBean(achar, simpleFinding);

		//FindingBean findingBean = achar.getTheFinding();
		String theFindingId = String.valueOf(simpleFinding.getFindingId());

		simpleFinding.transferToFindingBean(findingBean);

		if (!validateEmptyFinding(request, findingBean, editBean.getErrors())) {
			return editBean;
		}

		// setup domainFile uri for fileBeans
		SampleBean sampleBean = (SampleBean) request.getSession().getAttribute("theSample");
		String internalUriPath = Constants.FOLDER_PARTICLE
				+ '/'
				+ sampleBean.getDomain().getName()
				+ '/'
				+ StringUtils.getOneWordLowerCaseFirstLetter(achar
						.getCharacterizationName());

		findingBean.setupDomain(internalUriPath, SpringSecurityUtil.getLoggedInUserName());
		characterizationService.saveFinding(findingBean);
		achar.addFinding(findingBean);

		//transfer other data fields of the char
		editBean.transferToCharacterizationBean(achar);

		// also save characterization
		if (!validateInputs(request, achar, editBean.getMessages())) {
			return editBean;
		}

		this.saveCharacterization(request, achar, editBean);
		characterizationService.assignAccesses(achar.getDomainChar(), findingBean.getDomain());
		//this.checkOpenForms(achar, theForm, request);
		InitCharacterizationSetup.getInstance()
			.persistCharacterizationDropdowns(request, achar);

		request.setAttribute("anchor", "result");
		// return to setupUpdate to retrieve the data matrix in the correct
		// form from database
		// after saving to database.
		request.setAttribute("charId", achar.getDomainChar().getId().toString());
		request.setAttribute("charType", achar.getCharacterizationType());

		return setupUpdate(request, String.valueOf(editBean.getParentSampleId()), achar.getDomainChar().getId().toString(),
				achar.getClassName(), achar.getCharacterizationType());
	}

	public SimpleFindingBean saveFile(HttpServletRequest request, SimpleFindingBean simpleFinding)
			throws Exception {

		CharacterizationBean achar = (CharacterizationBean) request.getSession().getAttribute("theChar");
		SimpleCharacterizationEditBean editBean =
				(SimpleCharacterizationEditBean) request.getSession().getAttribute("theEditChar");
		SampleBean currentSample = (SampleBean) request.getSession().getAttribute("theSample");

		request.getSession().setAttribute("sampleId", String.valueOf(editBean.getParentSampleId()));

		FindingBean findingBean = this.findMatchFindingBean(achar, simpleFinding);
		findingBean =  this.transferSimpleFinding(simpleFinding, findingBean);

		int theFileIndex = simpleFinding.getTheFileIndex();
		FileBean theFile = simpleFinding.transferToNewFileBean();

		simpleFinding.getErrors().clear();

		// create a new copy before adding to finding
		FileBean newFile = theFile.copy();

		if (currentSample == null) //should not be
			currentSample = setupSampleById(String.valueOf(editBean.getParentSampleId()), request);

		// setup domainFile uri for fileBeans
		String internalUriPath = Constants.FOLDER_PARTICLE
				+ '/'
				+ currentSample.getDomain().getName()
				+ '/'
				+ StringUtils.getOneWordLowerCaseFirstLetter(achar
						.getCharacterizationName());
		newFile.setupDomainFile(internalUriPath, SpringSecurityUtil.getLoggedInUserName());

		String timestamp = DateUtils.convertDateToString(new Date(),
				"yyyyMMdd_HH-mm-ss-SSS");
		byte[] newFileData = (byte[]) request.getSession().getAttribute("newFileData");

		if(!theFile.getDomainFile().getUriExternal()){
			if(newFileData!=null){
				newFile.setNewFileData((byte[]) request.getSession().getAttribute("newFileData"));

				logger.debug("File path: " + newFile.getDomainFile().getUri());
			} else if(theFile.getDomainFile().getId()!=null){
				theFile.getDomainFile().setUri(theFile.getDomainFile().getName());
			}else {
				newFile.getDomainFile().setUri(null);
			}
		}

		this.validateFileBean(request, simpleFinding.getErrors(), theFile);
		if (simpleFinding.getErrors().size() > 0)
			return simpleFinding;

		findingBean.addFile(newFile, theFileIndex);
		findingBean.setupDomain(internalUriPath, SpringSecurityUtil.getLoggedInUserName());
		characterizationService.saveFinding(findingBean);

		achar.addFinding(findingBean);
		simpleFinding.transferFromFindingBean(request, findingBean);

		request.setAttribute("anchor", "submitFinding");
//		this.checkOpenForms(achar, theForm, request);
//		InitCharacterizationSetup.getInstance()
//			.persistCharacterizationDropdowns(request, achar);

		request.getSession().removeAttribute("newFileData");
		request.getSession().setAttribute("theChar", achar);

		/// save char to session
		return simpleFinding;
	}

	private FindingBean transferSimpleFinding(SimpleFindingBean simpleFinding, FindingBean finding) {
		//FindingBean finding = new FindingBean();
		finding.setColumnHeaders(simpleFinding.getColumnHeaders());
		FileBean theFile = new FileBean();
		File file = new File();
		file.setCreatedBy(simpleFinding.getTheFile().getCreatedBy());
		file.setCreatedDate(simpleFinding.getTheFile().getCreatedDate());
		file.setId(simpleFinding.getTheFile().getId());
		file.setTitle(simpleFinding.getTheFile().getTitle());
		file.setType(simpleFinding.getTheFile().getType());
		file.setDescription(simpleFinding.getTheFile().getDescription());
		theFile.setKeywordsStr(simpleFinding.getTheFile().getKeywordsStr());
		theFile.setDomainFile(file);
		finding.setTheFile(theFile);
		finding.setNumberOfColumns(simpleFinding.getNumberOfColumns());
		finding.setNumberOfRows(simpleFinding.getNumberOfRows());
		finding.setTheFileIndex(simpleFinding.getTheFileIndex());

		List<Row> rowList = new ArrayList<Row>();
		for(SimpleRowBean rowBean : simpleFinding.getRows()){
			Row row = new Row();
			List<TableCell> cellList = new ArrayList<TableCell>();
			for(SimpleCell cell : rowBean.getCells()){
				TableCell tbCell = new TableCell();
				tbCell.setColumnOrder(cell.getColumnOrder());
				tbCell.setDatumOrCondition(cell.getDatumOrCondition());
				tbCell.setCreatedDate(cell.getCreatedDate());
				tbCell.setValue(cell.getValue());
				cellList.add(tbCell);
			}
			row.setCells(cellList);
			rowList.add(row);
		}
		finding.setRows(rowList);
		List<FileBean> fileList = new ArrayList<FileBean>();
		for(SimpleFileBean fileBean : simpleFinding.getFiles()){
			file = new File();
			theFile = new FileBean();
			file.setCreatedBy(fileBean.getCreatedBy());
			file.setCreatedDate(fileBean.getCreatedDate());
			file.setId(fileBean.getId());
			file.setTitle(fileBean.getTitle());
			file.setUriExternal(fileBean.getUriExternal());
			file.setUri(fileBean.getUri());
			file.setType(fileBean.getType());
			file.setDescription(fileBean.getDescription());
			theFile.setKeywordsStr(fileBean.getKeywordsStr());

			theFile.setExternalUrl(fileBean.getExternalUrl());
			theFile.setDomainFile(file);
			fileList.add(theFile);
		}
		finding.setFiles(fileList);
		return finding;
	}

	public SimpleFindingBean removeFile(HttpServletRequest request, SimpleFindingBean simpleFinding)
			throws Exception {

		CharacterizationBean achar = (CharacterizationBean) request.getSession().getAttribute("theChar");
		SimpleCharacterizationEditBean editBean =
				(SimpleCharacterizationEditBean) request.getSession().getAttribute("theEditChar");

		FindingBean findingBean = this.findMatchFindingBean(achar, simpleFinding);
		int theFileIndex = simpleFinding.getTheFileIndex();
		findingBean.removeFile(theFileIndex);
		findingBean.setTheFile(new FileBean());
		request.setAttribute("anchor", "submitFinding");

		simpleFinding.transferFilesFromFindingBean(request, findingBean.getFiles());

		//this.checkOpenForms(achar, theForm, request);
		//return mapping.findForward("inputForm");

		return simpleFinding;
	}

	/**
	 *
	 * @param request
	 * @param simpleFinding
	 * @return
	 * @throws Exception
	 */
	public SimpleFindingBean drawMatrix(HttpServletRequest request, SimpleFindingBean simpleFinding)
			throws Exception {

		CharacterizationBean achar = (CharacterizationBean) request.getSession().getAttribute("theChar");
		SimpleCharacterizationEditBean editBean =
				(SimpleCharacterizationEditBean) request.getSession().getAttribute("theEditChar");
		request.setAttribute("anchor", "result");

		FindingBean findingBean = this.findMatchFindingBean(achar, simpleFinding);
		simpleFinding.transferTableNumbersToFindingBean(findingBean);

//		if (request.getParameter("removeColumn") != null) {
//			int columnToRemove = Integer.parseInt(request
//					.getParameter("removeColumn"));
//			findingBean.removeColumn(columnToRemove);
//			this.checkOpenForms(achar, theForm, request);
//			return mapping.findForward("inputForm");
//		} else if (request.getParameter("removeRow") != null) {
//			int rowToRemove = Integer.parseInt(request
//					.getParameter("removeRow"));
//			findingBean.removeRow(rowToRemove);
//			this.checkOpenForms(achar, theForm, request);
//			return mapping.findForward("inputForm");
//		}
		int existingNumberOfColumns = findingBean.getColumnHeaders().size();
		int existingNumberOfRows = findingBean.getRows().size();

		if (existingNumberOfColumns > findingBean.getNumberOfColumns()) {
//			ActionMessages msgs = new ActionMessages();
//			ActionMessage msg = new ActionMessage(
//					"message.addCharacterization.removeMatrixColumn");
//			msgs.add(ActionMessages.GLOBAL_MESSAGE, msg);
//			saveMessages(request, msgs);
//

//			findingBean.setNumberOfColumns(existingNumberOfColumns);
//			//this.checkOpenForms(achar, theForm, request);
//			return mapping.getInputForward();
		}
		if (existingNumberOfRows > findingBean.getNumberOfRows()) {
//			ActionMessages msgs = new ActionMessages();
//			ActionMessage msg = new ActionMessage(
//					"message.addCharacterization.removeMatrixRow");
//			msgs.add(ActionMessages.GLOBAL_MESSAGE, msg);
//			saveMessages(request, msgs);
//			findingBean.setNumberOfRows(existingNumberOfRows);
//			this.checkOpenForms(achar, theForm, request);
//			return mapping.getInputForward();
		}

		findingBean.updateMatrix(findingBean.getNumberOfColumns(),
				findingBean.getNumberOfRows());

		InitCharacterizationSetup.getInstance()
			.persistCharacterizationDropdowns(request, achar);

		simpleFinding.transferFromFindingBean(request, findingBean);
		simpleFinding.setColumnHeaders(findingBean.getColumnHeaders());
		simpleFinding.setDefaultValuesForNullHeaders();

		request.setAttribute("anchor", "submitFinding");

		//this.checkOpenForms(achar, theForm, request);
		// set columnHeaders in the session so jsp can check duplicate columns
		request.getSession().setAttribute("columnHeaders",
				findingBean.getColumnHeaders());
		//return mapping.findForward("inputForm");

		return simpleFinding;
	}

	public SimpleCharacterizationEditBean deleteFinding(HttpServletRequest request,
			SimpleFindingBean simpleFinding)
			throws Exception {

		CharacterizationBean achar = (CharacterizationBean) request.getSession().getAttribute("theChar");
		SimpleCharacterizationEditBean editBean = (SimpleCharacterizationEditBean) request.getSession().getAttribute("theEditChar");

		FindingBean dataSetBean = this.findMatchFindingBean(achar, simpleFinding);

		characterizationService.deleteFinding(dataSetBean.getDomain());
		characterizationService.removeAccesses(achar.getDomainChar(), dataSetBean.getDomain());

		achar.removeFinding(dataSetBean);
		request.setAttribute("anchor", "result");

		//this.checkOpenForms(achar, theForm, request);
		InitCharacterizationSetup.getInstance().persistCharacterizationDropdowns(request, achar);

		return setupUpdate(request, String.valueOf(editBean.getParentSampleId()), achar.getDomainChar().getId().toString(),
				achar.getClassName(), achar.getCharacterizationType());
	}

	public SimpleCharacterizationEditBean deleteExperimentConfig(HttpServletRequest request,
			SimpleExperimentBean simpleExpConfig) throws Exception {

		CharacterizationBean achar = (CharacterizationBean) request.getSession().getAttribute("theChar");
		SimpleCharacterizationEditBean editBean =
				(SimpleCharacterizationEditBean) request.getSession().getAttribute("theEditChar");

		editBean.getErrors().clear();
		editBean.getMessages().clear();

		ExperimentConfigBean configBean = achar.getTheExperimentConfig();
		simpleExpConfig.transferToExperimentConfigBean(configBean);

		characterizationService.deleteExperimentConfig(editBean.getParentSampleId() + "", configBean.getDomain());
		logger.debug("Experiment config deleted");
		achar.removeExperimentConfig(configBean);

		if (validateInputs(request, achar, editBean.getMessages())) {
			logger.debug("char validated");
			this.saveCharacterization(request, achar, editBean);
			logger.debug("Char saved");
		}

		characterizationService.removeAccesses(achar.getDomainChar(), configBean.getDomain());
		logger.debug("Access removed");
		//this.checkOpenForms(achar, theForm, request);
		InitCharacterizationSetup.getInstance()
			.persistCharacterizationDropdowns(request, achar);

		return setupUpdate(request, String.valueOf(editBean.getParentSampleId()), achar.getDomainChar().getId().toString(),
				achar.getClassName(), achar.getCharacterizationType());
	}

	/**
	 * Method to support setColumnOrder rest service
	 * @param request
	 * @param simpleFinding
	 * @return
	 * @throws Exception
	 */
	public SimpleFindingBean updateColumnOrder(HttpServletRequest request,
			SimpleFindingBean simpleFinding) throws Exception {

		CharacterizationBean achar = (CharacterizationBean) request.getSession().getAttribute("theChar");
//		SimpleCharacterizationEditBean editBean =
//				(SimpleCharacterizationEditBean) request.getSession().getAttribute("theEditChar");

		FindingBean findingBean = findMatchFindingBean(achar, simpleFinding);
		simpleFinding.transferColumnOrderToFindingBean(findingBean);

		findingBean.updateColumnOrder();

		simpleFinding.transferFromFindingBean(request, findingBean);

		request.setAttribute("anchor", "submitFinding");
		//this.checkOpenForms(achar, theForm, request);
		InitCharacterizationSetup.getInstance()
			.persistCharacterizationDropdowns(request, achar);

		return simpleFinding;
	}

	protected FindingBean findMatchFindingBean(CharacterizationBean achar,
			SimpleFindingBean simpleFinding)
	throws Exception {

		List<FindingBean> findingBeans = achar.getFindings();
		if (findingBeans == null)
			throw new Exception("Current characterization has no finding matching input finding id: " + simpleFinding.getFindingId());

		for (FindingBean finding : findingBeans) {
			if (finding.getDomain() != null) {
				Long id = finding.getDomain().getId();
				if (id == null && simpleFinding.getFindingId() == 0 || //could be a new finding bean added when saving a file
						id != null && id.longValue() == simpleFinding.getFindingId()) {
					achar.setTheFinding(finding);
					return finding;
				}
			}
		}

		if (simpleFinding.getFindingId() <= 0) {//new finding
			FindingBean newBean = new FindingBean();
			achar.setTheFinding(newBean);
			return newBean;
		}

		throw new Exception("Current characterization has no finding matching input finding id: " + simpleFinding.getFindingId());
	}

	protected ExperimentConfigBean findMatchExperimentConfig(CharacterizationBean achar, SimpleExperimentBean simpleExp) throws Exception
	{
		long expId = simpleExp.getId();

		if (expId <= 0)
			return achar.getTheExperimentConfig();

		List<ExperimentConfigBean> expConfigs = achar.getExperimentConfigs();

		if (expConfigs == null)
			throw new Exception("Current characterization has null experiment config list. This should not happen");

		for (ExperimentConfigBean expConfig : expConfigs) {
			if (expConfig.getDomain() != null && expConfig.getDomain().getId() != null) {
				if (expId == expConfig.getDomain().getId().longValue())
					return expConfig;
			}

		}

		throw new Exception("Current characterization has no Experiment config matching input experiment id: "
		+ expId);
	}

//	private void checkOpenForms(CharacterizationBean achar,
//			DynaValidatorForm theForm, HttpServletRequest request)
//			throws Exception {
//
//		achar.updateEmptyFieldsToNull();
//		String dispatch = request.getParameter("dispatch");
//		String browserDispatch = getBrowserDispatch(request);
//
//		HttpSession session = request.getSession();
//		Boolean openFile = false, openExperimentConfig = false, openFinding = false;
//		if (dispatch.equals("input") && browserDispatch.equals("addFile")) {
//			openFile = true;
//		}
//		session.setAttribute("openFile", openFile);
//		if (dispatch.equals("input")
//				&& browserDispatch.equals("saveExperimentConfig")) {
//			openExperimentConfig = true;
//		}
//		session.setAttribute("openExperimentConfig", openExperimentConfig);
//		if (dispatch.equals("input")
//				&& (browserDispatch.equals("saveFinding") || browserDispatch
//						.equals("addFile")) || dispatch.equals("addFile")
//				|| dispatch.equals("removeFile")
//				|| dispatch.equals("drawMatrix")
//				|| dispatch.equals("getFinding")
//				|| dispatch.equals("resetFinding")
//				|| dispatch.equals("updateColumnOrder")) {
//			openFinding = true;
//		}
//		session.setAttribute("openFinding", openFinding);
//
//		InitCharacterizationSetup.getInstance()
//				.persistCharacterizationDropdowns(request, achar);
//
//		/**
//		 * If user entered customized Char Type/Name, Assay Type by selecting
//		 * [other], we should show and highlight the value on the edit page.
//		 */
//		String currentCharType = achar.getCharacterizationType();
//		setOtherValueOption(request, currentCharType, "characterizationTypes");
//
//		String currentCharName = achar.getCharacterizationName();
//		setOtherValueOption(request, currentCharName, "charTypeChars");
//
//		String currentAssayType = achar.getAssayType();
//		setOtherValueOption(request, currentAssayType, "charNameAssays");
//
//		// setup detail page
//		if (achar.isWithProperties()) {
//			String detailPage = null;
//			if (!StringUtils.isEmpty(achar.getCharacterizationType())
//					&& !StringUtils.isEmpty(achar.getCharacterizationName())) {
//				detailPage = InitCharacterizationSetup.getInstance()
//						.getDetailPage(achar.getCharacterizationType(),
//								achar.getCharacterizationName());
//			}
//			request.setAttribute("characterizationDetailPage", detailPage);
//		}
//		// if finding contains more than one column, set disableSetColumnOrder
//		// false
//		if (achar.getTheFinding().getNumberOfColumns() > 1
//				&& dataMatrixSaved(achar.getTheFinding())) {
//			request.setAttribute("setColumnOrder", true);
//		} else {
//			request.setAttribute("setColumnOrder", false);
//		}
//	}

	private Boolean dataMatrixSaved(FindingBean theFinding) {
		if (theFinding.getColumnHeaders() != null) {
			for (ColumnHeader header : theFinding.getColumnHeaders()) {
				if (header.getCreatedDate() == null) {
					return false;
				}
			}
		}
		return true;
	}

	/**
	 * Shared function for summaryExport() and summaryPrint(). Filter out
	 * unselected types when user selected one type for print/export.
	 *
	 * @param request
	 * @param compBean
	 */
	private List<String> filterType(HttpServletRequest request, String type,
			List<String> charTypes) {
		//String type = request.getParameter("type");
		List<String> filteredTypes = new ArrayList<String>();
		if( !StringUtils.isEmpty(type) && type.equals("all")) {
			filteredTypes = charTypes;
		} else if (!StringUtils.isEmpty(type) && charTypes.contains(type)) {
			filteredTypes.add(type);
		}
		request.setAttribute("characterizationTypes", filteredTypes);
		return filteredTypes;
	}

	private boolean validateCharacterization(HttpServletRequest request,
			CharacterizationBean achar, List<String> errors) {

		String charName = achar.getCharacterizationName();
		String charType = achar.getCharacterizationType();

		if (charType == null || charType.length() == 0) {
			errors.add("Characterization type can't be empty.");
			return false;
		}

		if (charName == null || charName.length() == 0) {
			errors.add("Characterization name can't be empty.");
			return false;
		}

		boolean status = true;
		if (charName.equalsIgnoreCase("shape")) {
			if (achar.getShape().getType() != null
					&& !StringUtils.xssValidate(achar.getShape().getType())) {

				errors.add(PropertyUtil.getProperty("sample", "achar.shape.type.invalid"));
				status = false;
			}
			if (achar.getShape().getMaxDimensionUnit() != null
					&& !achar.getShape().getMaxDimensionUnit()
							.matches(Constants.UNIT_PATTERN)) {

				errors.add(PropertyUtil.getProperty("sample", "achar.shape.maxDimensionUnit.invalid"));
				status = false;
			}
			if (achar.getShape().getMinDimensionUnit() != null
					&& !achar.getShape().getMinDimensionUnit()
							.matches(Constants.UNIT_PATTERN)) {

				errors.add(PropertyUtil.getProperty("sample", "achar.shape.minDimensionUnit.invalid"));
				status = false;
			}
		} else if (charName.equalsIgnoreCase(
				"physical state")) {
			if (achar.getPhysicalState().getType() != null
					&& !StringUtils.xssValidate(achar.getPhysicalState()
							.getType())) {

				errors.add(PropertyUtil.getProperty("sample", "achar.physicalState.type.invalid"));
				status = false;
			}
		} else if (charName.equalsIgnoreCase(
				"solubility")) {
			if (achar.getSolubility().getSolvent() != null
					&& !StringUtils.xssValidate(achar.getSolubility()
							.getSolvent())) {

				errors.add(PropertyUtil.getProperty("sample", "achar.solubility.solvent.invalid"));
				status = false;
			}
			if (achar.getSolubility().getCriticalConcentrationUnit() != null
					&& !achar.getSolubility().getCriticalConcentrationUnit()
							.matches(Constants.UNIT_PATTERN)) {

				errors.add(PropertyUtil.getProperty("sample", "achar.solubility.criticalConcentrationUnit.invalid"));
				status = false;
			}
		} else if (charName.equalsIgnoreCase(
				"enzyme induction")) {
			if (achar.getEnzymeInduction().getEnzyme() != null
					&& !StringUtils.xssValidate(achar.getEnzymeInduction().getEnzyme())) {
				errors.add(PropertyUtil.getProperty("sample", "achar.enzymeInduction.enzyme.invalid"));
				status = false;
			}
		}
		return status;
	}

	private Boolean validateInputs(HttpServletRequest request,
			CharacterizationBean achar, List<String> errors) {
		if (!validateCharacterization(request, achar, errors)) {
			return false;
		}
		return true;
	}

	private boolean validateEmptyFinding(HttpServletRequest request,
			FindingBean finding, List<String> errors) {

		if (finding.getFiles().isEmpty()
				&& finding.getColumnHeaders().isEmpty()) {
			errors.add(PropertyUtil.getProperty("sample", "achar.theFinding.emptyFinding"));
			return false;
		} else {
			return true;
		}
	}

	/**
	 * Copy "isSoluble" property from achar to Solubility entity.
	 *
	 * @param achar
	 */
	private void copyIsSoluble(CharacterizationBean achar) {
		Boolean soluble = null;
		String isSoluble = achar.getIsSoluble();
		if (!StringUtils.isEmpty(isSoluble)) {
			soluble = Boolean.valueOf(isSoluble);
		}
		if ("Solubility".equals(achar.getClassName())) {
			achar.getSolubility().setIsSoluble(soluble);
		}
	}

	public java.io.File download(String fileId, HttpServletRequest request) throws Exception {
		return downloadImage(characterizationService, fileId, request);
	}

	public String download(String fileId, HttpServletRequest request, HttpServletResponse response) throws Exception {
		return downloadFile(characterizationService, fileId, request, response);
	}

	protected boolean validCharTypeAndName(String charType, String charName, List<String> errors) {
		boolean valid = true;
		if (charType == null || charType.length() == 0) {
			errors.add("Characterization type can't be empty");
			valid = false;
		}

		if (charName == null || charName.length() == 0) {
			errors.add("Characterization name can't be empty");
			valid = false;
		}

		return valid;
	}

	/**
	 * Set up the input form for editing existing characterization
	 *
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public List<SimpleCharacterizationUnitBean> setupView(HttpServletRequest request, String sampleId, String charId, String charClassName, String charType)
			throws Exception
	{
		charId = super.validateCharId(charId);

		CharacterizationBean charBean = characterizationService.findCharacterizationById(charId);

		SimpleCharacterizationSummaryViewBean viewHelper = new SimpleCharacterizationSummaryViewBean();
		List<SimpleCharacterizationUnitBean> aBeanUnitList = viewHelper.tranferCharacterizationBeanData(request, charBean);

		return aBeanUnitList;
	}

	@Override
	public CurationService getCurationServiceDAO() {
		return curationServiceDAO;
	}

	@Override
	public SampleService getSampleService() {
		return sampleService;
	}

	@Override
	public SpringSecurityAclService getSpringSecurityAclService() {
		return springSecurityAclService;
	}

	@Override
	public UserDetailsService getUserDetailsService() {
		return userDetailsService;
	}

}


text:
Asia & International Markets
Assurance & Risk
Subscribe for daily news
Get in contact with the KPMG Media Team
Implementing a circular economy fundamental to an environmentally and economically sustainable future.
May 1, 2020 in Business & Economy
Dr George Verikios
Director, KPMG Economics
Dr Brendan Rynne
Chief Economist, KPMG Australia
Implementing a circular economy is fundamental to an environmentally and economically sustainable future. Put simply, a circular economy involves more use and re-use of the industrial production system so we get an extended life out of intermediate goods, with a wide array of positive economic outcomes. Our modelling, commissioned by the CSIRO, shows by embracing a circular economy we can expect an increase in GDP of $23bn by 2025.
Looking further to 2047-48, the benefit of a circular economy will likely rise to a present value of $210 billion in GDP and an additional 17,000 full-time equivalent (FTE) jobs for Australia.
The concept of a circular economy is grounded in the idea of sustainability and resource efficiency, and seeks to keep products, commodities and resources 'in the loop' for as long as possible. Keeping them 'in the loop' means maximising the utilisation and extending the lifespan of what we use to increase resource productivity and reduce waste. To achieve this, processes, activities and technologies need to be designed and developed with reusing and recycling in mind.
The transition to a circular economy is an ambitious movement and while the core motivation is to minimise environmental impacts such as reducing greenhouse gas emissions or primary resource use, our study indicates a considerable economic benefit. A circular economy not only extends the usable life of products but also extends their value, creates new jobs and raises economic growth.
Three key areas – food, transport and the built environment are vital to a low-waste and high resource efficient pipeline with opportunities such as energy efficiency and food waste reductions representing the greatest impacts in monetary terms, due to the importance of these sectors in the Australian economy.
The growing amount of food waste is a global concern. Reduction requires a concerted effort at an individual level. Cutting down food waste as a proportion of the total household food consumption directly translates into reduced household expenditure.
The progression from petrol to electricity fuelled cars. Electric vehicles have had a slow start in the Australian vehicles market due to a higher upfront purchasing cost and perceptions around convenience. Analysis of increased switching from fuel-based to electric-powered vehicles reveals the potential long-term ongoing saving in costs of fuel compared to electricity and lower maintenance costs of electric vehicles.
Converting agricultural organic waste to biogas, which can then be processed to generate electricity. The biogas-generated electricity has a lower per unit cost as compared to the retail price thus resulting in millions of dollars saved by the agricultural sector.
Although we have considered a broad range of sectors and industries that encompass the key areas of economic activity in Australia, our list is by no means exhaustive and only identifies areas where the circular opportunities are most viable.
While our projections are a conservative estimate of the impacts of a move towards a circular economy they provide an understanding of the potential magnitude of positive impacts from its adoption. This report highlights a substantial pay-off above and beyond its environmental benefits, reinforcing findings from other countries and jurisdictions.
While the economic benefits of the circular economy may seem modest given the current size of the government's stimulus package, this sort of innovation and greater productivity is exactly what is needed by Australia as we move out of the COVID-19 emergency.
We are facing unprecedented debt levels and focusing on higher taxes and reduced spending will not be enough. Greater productivity is the key to repaying this debt and more efficient and less wasteful production techniques as shown by this report on the circular economy could be an important part of that.
Tags circular economy, CSIRO
Too good to throw away: why the circular economy matters
Mar 9, 2020 In
Tweets by @kpmgaustralia
Subscribe for daily news Subscribe
© 2021 KPMG, an Australian partnership and a member firm of the KPMG global organisation of independent member firms affiliated with KPMG International Limited, a private English company limited by guarantee. All rights reserved.

redpajama_set_name: RedPajamaCommonCrawl


You will not experience problems like how to get around and how to get in the Soponya area where you go for vacation on our web site.
Where is the nearest station, how do I get to the airport, where is the airport taxi, where is the uber Soponya, how to use the airport shuttle will be answered very soon on this page.
This entry was posted in Fejer Airport Shuttle Service, Hungary and tagged How to go Soponya, Soponya airport shuttle bus, Soponya airport shuttle service, Soponya transportation, Soponya Uber, Uber Soponya.


Today, I'm going to teach you how to setup a private proxy server from your home.
There are a lot of situations when you may require using a proxy server.
For example, you are using free Wi-Fi in a hotel or in a cafe with free WiFi.
There is no guarantee that the network is secure and scammers don't try to scan and intercept your bank card data or logins and passwords to your personal pages.
Or you would like to hide your current IP address because accessing the resource you use requires the anonymity.
Or you got a search engine ban because of frequent connection requests.
In any of these situations using the proxy server is the best solution.
There are two options to launch a proxy server: find a private proxy service (paid or free) or create your own private proxy server.
The first option is not always safe and no one can be sure that no one else uses the same IP address with you.
In this case, someone's spam activity can lead to proxy server ban. So, using your own private proxy is a good solution.
5. The proxy server is ready!
This step is necessary in order to provide the high level of security. Search online for a hosting provider with SSH support.
Most modern providers support SSH connection by default and without additional payments. Good hosting costs about several dollars a month.
Theoretically, you can find free service, but paid ones will work better and safer. Contact tech support how to use SSH connection.
Attention! Make sure that the hosting provider allows creating a proxy server. If it's forbidden, your account can be banned!
After getting the hosting with SSH, you require the PuTTY program to create a local proxy server.
PuTTY is an open source client for various remote access protocols (SSH, Telnet, rlogin, TCP). Used to connect to a remote computer (for example, a web server) and execute various commands on it.
PuTTY logs and allows you to customize fonts, colors and resolution of the console, allows you to store keys of authorization in your memory, supports working through a proxy server.
In addition, PuTTY is free and does not require any special configuration, except for passwords for accessing the server, username, and password.
Download the program for free from the official website of the program: www.putty.org.
Having launched the program, you will see a settings window. In the Host Name field, enter the domain address or IP address of your server.
You may take this information from your hosting provider control panel. In the Port field, enter the port, for example, 22.
Now go to Connection — SSH — Tunnels and add a port number. To do this, in the Source port field, enter the port of the future local proxy server, for example, 8888.
Check the Dynamic option and click the Add button.
After that, the port will be displayed in the Forwarded ports field and will look like D8888.
In order to avoid configuring the app each time, save the current settings.
To do this, go back to the Session category in the left sidebar, select Default settings and click the Save button.
Having configured the program, open the session to create a local proxy server. To do this, click the Open button in the right bottom corner.
If you connect to the server for the first time, PuTTY will notify you that it does not have information about this server. To confirm the connection click Yes.
Attention! We strongly recommend connecting to your server for the first time through a reliable network.
Then the program will ask for your login and password (when entering the password, the cursor will not move, and the asterisks will not appear — this is normal).
When you enter your login and password, the information about the server appears on the screen, and your proxy will be available at 127.0.0.1:8888 or localhost:8888.
Enter the address in any browser to make if everything works correctly.
In most cases, you will see "localhost" written in the corner.
At the end of the work, you may close the black window of the PuTTY, confirming shutting down the server.
To use the created private proxy server in the browser, you need to configure the connection through SOCKS5 proxy server, specifying 127.0.0.1:8888 or localhost:8888 in the settings.
Other programs in most cases can be configured in the same way. For example, let's try to configure Google Chrome.
Select Menu — Settings — Advanced — System — Open proxy settings.
In the Internet Properties window select the Connections tab and click the LAN Settings button.
In the "Configure LAN Settings" window, check "Use a proxy server for your LAN" box (in the future, to quickly turn on and off the proxy, you can simply check or uncheck this box) and click on the "Advanced" button.
In the "Proxy server settings" window, fill in Socks field: address — localhost, port — 8888. Leave all the other fields empty.
Now close all the windows by clicking on the "OK" button. Your browser is ready to work through a proxy.
To check and make sure that you actually go online through a server, open your browser and go to any service that determines your IP address and shows the detailed information about it.
For example, one of the most popular services is WhatIsMyIP.com®. Compare the IP address with the proxy server turned off and on.
As you see, creating and using your own private proxy server is not so difficult as it may seem. Just follow the tutorial and you will be successful.


What is the Mississippi River Basin?
What is the Mississippi River Basin, and why is it so important?
The Mississippi River is, to put it simply, big. It flows 2,350 miles from its source at Lake Itasca in Minnesota through the center of the continental United States to the Gulf of Mexico. It is a major migration route for North American birds and fish, and is home to around 260 species of fish and over 300 species of birds. It is one of the world's most important commercial waterways. Every year, million of tons of rice from farms in Arkansas and Louisiana are transported via barge. It's final destination? China. Rice is just one of many goods transported domestically and internationally via the Mississippi.
Beginning in the 19th century, the Mississippi became an important transportation channel for commerce, industry, and recreation. Engineering the river to provide navigation and control flooding continues to be a management issue. Engineers have to consider changing floodplain regions as a result of the natural shift of the river's course, as well as nutrient runoff from agriculture located in the floodplains. To increase navigation potential, engineer's connected Lake Michigan and the Illinois River, making yet another path for invasive species.
The Mississippi River Basin Watershed, the area drained by a river's tributaries, is about 1.2 million square miles, and includes all or parts of 31 states and two Canadian provinces, about 40% of the continental United States. In Wisconsin, tributaries include the Rock River, Wisconsin River, Chippewa River, and St. Croix River, among many others.
Balancing the needs and demands of navigation, agriculture, recreation, industry, and wildlife continues to be a challenge. There are no easy answers, as several global entities, compete for their interests in the Basin region. This complex ecological system will continue to be an important part of the conversation about water and life.
To read about organizations committed to responsible management of the Upper Mississippi Region, click here.


Age-Stop Switzerland, the premium Swiss skincare brand is offering luxury anti-aging skincare formulations that have been carefully developed to deliver amazing anti-aging results. Those who have been battling the problems of wrinkles, fine lines and other visible signs of aging can use the best face cream from Age-Stop Switzerland to achieve their beauty goals.
The range of products offered by the company contains scientifically advanced ingredients such as bio-mimetic peptides, patented Swiss snow algae, Alpine flower stem cells, Hyaluronic Acid, oxygen-fusion, vitamins, and extracts of bio-available precious stones in unique combinations.
At Age-Stop Switzerland, the focus is on incorporating the fabled Swiss know-how and the remarkable French flair for beauty into creating anti-aging skincare products that have an exceptional ability to provide fast and measurable results. As a fitting compliment to their premium status, these products are presented in stylish packages and are extremely easy to use as well.
According to the company spokesperson, the reputation of Switzerland as the best-known precise time-keepers across the globe finds a solid connection in these high-value products as well. These products have been created by some of the best brains in skincare and anti-aging technology.
The skincare experts at Age Stop Switzerland have researched extensively to unlock the secrets to healthy aging and reversing the effects of aging on the skin. The entire range of these innovative products reflects the pristine purity and impeccable quality that Switzerland proudly represents. These premium products contain some of the most exclusive ingredients that are simply not available in other skincare brands available across the world.
Customers ordering these powerful and proven anti-aging brands from Age-Stop Switzerland can enjoy a host of other features such as free worldwide shipping, 30-day money back guarantee on all products, and a secure payment platform. They can order these award-winning skincare products conveniently now.


Let us be the one who you trust to deliver the right upholstery cleaning for you and we will not let you down. We work hard because we know what it is going to take to do the job right for you. We are here to be what you need and be a solution for you so that you can be sure you have got someone taking care of your upholstery cleaning who really knows what they are doing. We are going to give you a result that you will be pleased with when we are finished with the task.
Our Upholstery Cleaning in Balgonie knows quality and when you want someone to deliver the best, we are going to strive to get you what it takes. Our team knows what it takes to give you upholstery services that will be able to meet all of your needs. We use only the best tools and they allow us to really get a deep clean and do the job well for you.
For any quality Upholstery Cleaning in Balgonie help that you might need, we are ready to give you what it takes in order to do the upholstery cleaning in the right way. We are not afraid of working hard in order to get you what you need and get your needs met. Never worry about your upholstery needs again when you find out how we will be able to tackle them for you and deliver the quality results you have been waiting for. Don't spend any more time doing the cleaning on your own because that is what we are here to do for you. Our team will not hesitate to take your call and get started right away, so think of us the next time you want to get your upholstery needs taken care of.


text:
Parkinson's Academy > Research Engagement > Is disease modification in Parkinson's a reality?
For a number of years we have received feedback at the Parkinson's Academy about including sessions about research. Taking these responses and working with The Cure Parkinson's Trust (CPT) and NIHR leads Dr Camille Carroll, Professor Oliver Bandmann and the Academy's Dr Peter Fletcher, we designed the Research Engagement meeting for professionals who are becoming or aspire to become involved with Parkinson's research on many different levels. Each week we are posting a blog to look at the meeting's speaker sessions in more detail.
Dr Richard Wyse, The Cure Parkinson's Trust
CPT's Dr Richard Wyse opened the meeting by discussing whether disease modification in Parkinson's could be a reality.
As we know, Parkinson's symptomatic therapies have many imperfections. Encouragingly there is research into both better symptomatic and disease modifying treatments. At CPT however our sole focus is to halt progression of the disease and ultimately to reverse it. The charity has preclinical and regenerative medicine programmes, but it also has built a very large clinical trials programme of drugs, many repurposed from other disease areas. These are prioritised and evaluated by a committee of Parkinson's experts of world renown.
Called the Linked Clinical Trials initiative, since its inception the programme has evaluated more than 2,000 drugs and 100 different biological targets relevant to Parkinson's, and developed 173 detailed dossiers, of which 120 have been discussed by the Committee. This has led to the prioritisation of 49 drugs and bioactive compounds, of which 10 drugs have moved into clinical trials and a further seven are due to start in the coming year.
Good examples of trials in the programme include:
PD-Stat a clinical trial of 230 people with mid-stage Parkinson's using simvastatin is currently running across 23 centres in England
cureparkinsons.org.uk/the-simvastatin-trial-the-facts
content.iospress.com/articles/journal-of-parkinsons-disease/jpd171203
Aim-PD a small study of people with GBA and idiopathic Parkinson's testing a drug called Ambroxol, usually used to alleviate mucus build-up, has just completed at the Royal Free Hospital in London
And the now completed 2017 study of Bydureon, a once weekly injectable treatment for type II diabetes which produced interesting results and is now moving forward into further trials
cureparkinsons.org.uk/news/bydureonresults
ncbi.nlm.nih.gov/pubmed/30269406
This dynamic programme of clinical trials of potentially disease modifying treatments has created the opportunity for more interested and dedicated professionals to join in with this growing research effort.
Listen to this presentation:
→ More articles and videos from this meeting
Posted in: Research Engagement


For any marketing assignment, a good market research is very important. It is only through a good market research that you can create a better marketing strategy. Hence, before starting on your marketing assignment, you need to make sure that you are doing a good marketing research so that you can create a better research project.
Here, the term "Marketing Research" and "Market Research" are seen differently by the experts. One refers to the different marketing processes while the latter refers only to the markets. The details of the different market analysis, needs, its size as well as different competitionsis obtained through the market research.
The Marketing professionals employ two different kinds of research techniques namely primary research and secondary research. Qualitative and Quantitative research are the two divisions of Primary research. In any business planning and strategy, market research plays a very significant role. However, before starting with the business planning, there are few significant things that are required to be taken care of. The Market research can be performed by basically two techniques.
The first is the market information and market segmentation which gives an information about the demand and supply of the market. A detailed analysis of social, technical and legal aspects of the market is provided by market research assignment help. When the market is divided on the basis of the needs and requirements of a specific segment of the market then it is known as market segmentation. Market segmentation is used widely to segment or divides the market on the basis of the differences in personality and demographics.
The second is the SWOT analysis which shows an organization's Strength, Weakness, Opportunities, and Threats. SWOT plays a vital role as with the help of it, a business is staged and it continues to exist throughout the entire life of the business. It also plays a significant role in the analysis of the design of the product. Other information like an evaluation of the competitors, products, customer behavior are provided by SWOT Analysis.
There is a team of professional writers who have immense experience in writing academic projects at Total Assignment Help. Their primary aim is to solveyour homework assignments with a good research. At Total Assignment Help, the rule of ASAP (Affordability, Availability, Professionalism and Plagiarism free solution) is strictly followed.
The tutors work according to the requirements of the students and that is the reason why the assignments are solved in a right and proper way. Plagiarism is a sin when it comes to assignment writing. It is very easy to copy and paste stuff from the internet and submit it to the students. At Total Assignment Help, we check all the assignments using Turnitin, Grammarly, and other tools that can help in providing a quality assignment. We also ensure a minimum of 2:1 grade in all the assignments. Last but not the least is sitting in any corner of the world, you can book our services and get the Marketing research assignment writing help.


What is Link Building? Definition and Resources Siege Media.
The first is from Backlinko. He has a great link building guide that will give you an in-depth starting point of how to do link building, the strategies behind link building, how to think about it, and thats a good place to start on the web. Jon Coopers Link Building Strategies. The second is from Point Blank SEO.
Introduction to Link Building For SEO Chapter 1.
Great link building demands well-developed skills across the board: content creation, marketing, programming, sales, and psychology are all part of the process. Links arent the whole SEO story, but they touch on many key factors that influence SEO, like popularity, authority, spamminess, and trustworthiness.
9 EASY Link Building Strategies That ANYONE Can Use.
Heres a syndicated version of our recent local SEO guide on another site.: Read our full guide to content syndication to learn precisely how to do this. Community site link building. Most people focus on building ONLY the highest quality links.
With that in mind, we'll' get you started with 33 ideas to help you build legitimate inbound links. Read on to see how to use these link building tools in your SEO strategy. Tools for Link Building. Maintain a steady blog with great content.
50 link building techniques checklist mangools blog.
Link building on Wikipedia isnt complicated but you should think tactical. The biggest con is that linking from Wikipedia will automatically generate new links because your site will be used as a reference. Jon Cooper wrote a Wikipedia for SEO guide you simply have to read.
Link Building Search Engine Optimization SEO SEO Workers.
Before you begin a link building campaign, you'll' need to make sure that you've' already determined which keywords to optimize your site for like every other part of your SEO campaigns, link building works using your primary keywords as its foundation.
The Importance of Link Building. Link building is an important aspect of SEO marketing. If you have not yet employed link building strategies in your marketing structure, you are possibly missing out on potential business. Using link building strategies will help you create high-quality SEO marketing campaigns that will help your business thrive.
24 Best Link Building Services To Buy Online Fiverr.
Become a Seller. Get The Best Link building Services. Find the best Link building services you need to help you successfully meet your project planning goals and deadline. Customers Reviews In link building Services. I will publish a guest post on my 73da finance blog, SEO backlink.


text:
Nutrition in crisis: healing the harm from bad science
30th Jan 2021 fmadmin Food for Thought 2
Crisis, you say. What crisis? If you're talking nutrition science, it's not just one crisis. Take your pick from related crises around nutrition in the US, the UK and South Africa – and most of the rest of the globe.
That's more good reason to read Nutrition in Crisis, Flawed Studies, Misleading Advice and the Real Science of Metabolism.
It's not new – it was published in 2019. The author is US biochemistry professor Richard David Feinman of the State University of New York (SUNY) Downstate Medical Center in Brooklyn, New York. He enjoys a reputation as a teacher with "a gift for making accessible the intricacies of the body's biochemistry".
The book's content remains relevant today. It is primarily about biochemistry and food metabolism. It is about why nutrition science is in such bad shape, scientifically and ethically – and a source of harm. It's also about one crisis in particular. Google misinformation, disinformation, fraud, nutrition science and carbohydrates and you'll come across all the evidence you could want to red-flag crisis.
Nutrition Scientist's Eagle Eye
Prof Richard Feinman
US science journalist Nina Teicholz writes on the cover that Feinman's book is "fascinating … full of original, interesting material by one of the original low-carb researchers whose grounding in the field goes back decades".
Feinman combines "a unique perspective with the experienced eye of a scientist", Teicholz says. He has had a "front-row seat to developments in the field of carbohydrates and metabolism over the past decades". This gives him "key insights into the latest research".
Teicholz is author of another groundbreaking book for your bookshelf: The Big Fat Surprise, Why Butter, Eggs and Cheese Belong in a Healthy Diet (Simon & Schuster, 2014)
In his book, Feinman demonstrates why it's impossible to write about nutrition science and escape the sociology and politics of medicine. These disciplines bedevil and infect nutrition science to the point of harm – and terminal illness.
That's in part – large part – a function of his view of science as "less about sophisticated measurements than about basic honesty". That's sobering but true.
If there were consensus among experts, it would be that misinformation, disinformation and fraud are rampant in nutrition science. And that real debates are around who are most culpable, why and the harm they cause.
Nutrition Science and Bizarre Breakdown
Feinman shows how best to resolve one pressing crisis affecting the health of millions worldwide. As he demonstrates, it's the logical outcome of establishment medical journals, private organisations and government health agencies promoting "low-fat, low-calorie dogma despite the scientific evidence to the contrary". That's a topic for a whole book on its own.
He calls misinformation around dietary fat and carbohydrate a "politically motivated breakdown in scientific practice". It is one that deeply discouraged him. Feinman didn't stay down for long. It's not in his nature. It became another motivation for him to write the book. He presents the evidence for the concept of metabolic syndrome that underlies the crisis. He rightly calls the identification of the syndrome "a great intellectual insight".
Click here to read: Cancer: Fung sees the future, cracks the code
Feinman defines metabolic syndrome as a collection of clinical markers of, among others, obesity, hypertension and so-called "atherogenic dyslipidemia" – lipid (blood fats). The latter are markers that many medical doctors still assume as contributing to cardiovascular disease (CVD – chiefly, heart attack and stroke). These together and in combination indicate risk of disease, he writes. He shows how relatively easy it is – and always has been – to offset that risk significantly with simple dietary change.
Insulin's role as a major contributing factor to the syndrome is another major focus. It points, as he writes, to "the importance of controlling dietary carbohydrate, the major stimulus for insulin secretion".
He finds that resistance "incomprehensible", even "bizarre" and "a source of real harm to patients". So do many of his colleagues. It is yet another example of a "disconnect from true science", Feinman says.
First, do no harm
He has deliberately aimed his book at scientists. They are, after all, first port of call as a source of solid, reliable evidence for treatment that "first does no harm". That makes his book important for medical doctors and more ordinary mortals.
One of Feinman's many strengths is writing style that makes it accessible and enjoyable to the lay reader. He takes readers on a journey of nutrition as applied biochemistry. It focuses on a question that invariably comes up during his lectures to medical students, conference presentations. It even comes up, he says, in private conversations about scientific experiments.
Click here to read: Vegetarian cookbook: Gift that goes on giving – even for meat-eaters!
The question: "What should I eat?"
Depending on his audience, Feinman goes into differing levels of technical detail. His bottom line is always the same and is the heart of this book: "The best diet is the one that works." That represents, as he explains it, a more scientific, logical perspective to nutrition than "you are what you eat".
Feedback loop
Instead, "you are what your metabolism does with what you eat". He explains that and why low-carb diets are – or should be, by now – the default diet for anyone with diabetes and metabolic syndrome. And why we all need to understand that idea, even if we are lucky enough currently not to have either condition. Luck, after all, has a horrible habit of running out.
Feinman plots the path to ensure you don't go down that road as so many have done and are doing, worldwide. He demonstrates why almost everything in biology is "connected with feedback". That idea is "fundamental yet widely ignored".
Cholesterol is one example. "Reducing dietary cholesterol will have limited effect (on your risk of heart attack or stroke) because of compensatory synthesis," Feinman writes. Similarly, if you stop eating carbohydrate, your body will simply respond by "synthesizing glucose and making other fuels available".
Click here to read: Cholesterol fears, fake news and age games: who plays?
This "grand idea" severely limits what you can do – as with cholesterol, or "looking ahead, trying to starve tumors by reducing glucose". But it also points to opportunities.
Those opportunities make his book a must-read.
Feinman's original area of research was in protein chemistry and enzyme mechanism, particularly in blood coagulation and related processes. However, his ongoing life influences have been food and chemistry.
World Turned Upside Down
His current interest is nutrition and metabolism, specifically in diet composition and energy balance. These inform and influence his teaching in the SUNY Medical School. They have made him a pioneer in incorporating nutrition into the biochemistry curriculum for medical doctors.
Feinman is also author of The World Turned Upside Down. The Second Low Carbohydrate Revolution (Duck in a Boat, 2014). In it, he describes how the science of carbohydrate restriction arose from "a rag‑tag collection of popular diets" to defeat "the powerful low‑fat army and become the default approach to health".
Sadly, when it comes to saturated fat, the low-fat army is still making forays and opening new fronts in the diet wars. The health consequences are evident in rising obesity, type 2 diabetes rates, as well as diet-related cancers and dementia diseases, such as Alzheimer's.
Hence the ongoing relevance of Feinman's latest book.
Nutrition In Crisis
Richard David Feinman
Vegetarian cookbook: gift that goes on giving, even for meat-eaters!
Flying Against The Odds: Pilot's path to surviving cancer
William L. Wilson, M.D.
30th Jan 2021 at 9:25 pm
As usual, this is an excellent and timely post.
fmadmin
31st Jan 2021 at 8:26 am
Thank you, Dr Wilson!


text:
The Kirkby Stephen and Smardalegill Viaduct walk in Northern England
West from Kirkby Stephen to pick up the dismantled railway line near Waitby. Along the railway line under Smardale Viaduct to Smardalegill Viaduct. South along a track to Smardale Bridge, then further south to the village of Ravenstonedale. East along minor roads and paths to the A683 at Tarn House, and after a short walk north-east along the A683, east following Tommy Road and a bridleway to the River Eden. North following A Pennine Journey through Nateby and back to Kirkby Stephen. A 14-mile walk in Northern England.
The view north over farmland near Smardale Hall.
The dismantled railway line through Smardale Gill.
Smardale Gill Viaduct
Smardale Gill Viaduct is a dramatic Grade 2 listed viaduct, 90 feet (27.5 metres) high and 184 yards (168 metres) long, with 14 arches.
The viaduct was constructed in 1861 by the noted Cumbrian engineer, Sir Thomas Bouch, for the South Durham & Lancaster Union Railway. The railway was built across the Pennines to take coke from County Durham to the iron and steel furnaces of Barrow and West Cumbria. At its peak, in the 1880s, over one million tons of coke a year were transported along the line.
The line was closed in 1962 because the Barrow steelworks closed. The Northern Viaduct Trust was established in 1989 to save the viaduct from demolition. Funds were raised to acquire and restore the viaduct, thereby ensuring that it would remain embedded in the landscape, to be enjoyed for generations to come.
Since then the trust has taken over and restored Podgill and Merrygill viaducts on the line east of Kirkby Stephen and has converted 1¼ miles of track bed into a permissive footpath.
Smardale Gill National Nature Reserve
One of the joys of Smardale Gill National Nature Reserve is its easy access. A wide path, of very little gradient, allows visitors to experience a range of truly glorious, unspoilt habitats, from ancient woodland to flower-rich limestone grassland. This landscape also holds interesting archaeology, from the Romano-British times through to the railway heyday. A visit to the nature reserve transports you to a truly remote area of landscape all easily accessible along its 3.5 mile (6 km) length.
The woodlands are ancient and semi-natural, meaning that there has been a constant covering of trees in the area since at least 1600. Within them there is a large amount of dead wood, providing important habitat for a vast number of insects and woodland birds.
The limestone grasslands of the nature reserve are internationally important. Between May and September, they burst into a glorious display of colour as the plants, which are much more abundant than the grasses, come into flower. These include melancholy thistle, knapweed, wood cranesbill, great burnet, northern marsh butterfly, fragrant and common spotted orchid, common rock rose, wild thyme, bird's-foot trefoil, salad burnet, limestone bedstraw, devil's-bit scabious, bloody cranesbill and fell wort.
Smardale Gill NNR is well known for its butterflies. The Scotch argus butterfly occurs at the southern limit of its natural range here; one of only two populations found in England. Adults can be seen flying from August to September and feeding on nectar from plants.
The nature reserve also supports the largest colony of northern brown argus butterfly in east Cumbria. It is on the wing during July. Other butterflies commonly seen at Smardale Gill NNR include dark green fritillary, small heath, small tortoiseshell, meadow brown, red admiral, common blue, comma and orange tip.
The river, Scandal Beck, is a tributary of the river Eden and has been designated within the River Eden and Tributaries Special Area of Conservation (SAC). This is due to its international importance for a range of globally endangered species including white-clawed crayfish, bullhead river lamprey, salmon and otter.
Smardale lime kilns
Limestone was probably first burnt in England by the Romans to provide the lime mortar needed for their buildings. But it was not until the last quarter of the 17th century that its use became widespread when increased prosperity led to the building of many of the stone farmhouses and barns which are a feature of the area. The lime needed for this was made in small field kilns, and there are the remains of over 300 in this district alone. Later, towards the end of the 18th century, burnt lime began to be used extensively for arable crops and to improve the quality of pasture land.
Later still, burnt lime was produced on a much larger scale for industrial purposes. The two Smardale kilns represent an interesting stage between the small field kilns, providing lime for local use, and the great lime works of Horton and Langcliffe. They were built to take advantage of the Tebay to Darlington railway line which was opened in 1861 and are contemporary with it. For some years they supplied lime for the steelworks at Darlington and Barrow, but the quality of the lime was considered not good enough and the kilns ceased to operate before the end of the century.
The method of burning was simple, but involved much hard work carting and carrying stone, and the fumes from the kiln could be noxious. The pot was filled with alternate layers of broken limestone and fuel, usually coal, or later, coke. It was lit from the draw hole and allowed to burn slowly at about 900 degrees centigrade for between two and ten days. The burnt lime, or quicklime, was then drawn out and in this case loaded directly onto the railway wagons standing in the siding. If it was to be used for mortar it had to be slaked by pouring water onto it in a mortar pit when it became hydrated lime. For use on the land it was allowed to stand in small heaps to be slaked by rain, or added to large compost heaps after which it could be spread on the fields.
Smardale Gill National Nature Reserve – limestone grassland and flowering plants
The limestone grasslands of the reserve are internationally important. There are two distinctive types.
The mountain hay meadow type contains a distinctive group of plants which is unique to the UK. It is estimated that only 1000 hectares of this type of grassland occur in the world. Between May and September, the meadow bursts into a glorious display of colour as the plants, which are much more abundant than the grasses, come into flower. Some of the flowering plants that can be found include melancholy thistle, lady's mantle, knapweed, wood cranesbill, twayblade and great burnett. Orchid species include northern marsh, fragrant and common spotted orchids.
Limestone grassland found in this area is dominated by blue moor grass (itself a rare species). Only 60,000 hectares of this type of grassland remain in the UK. This type of grassland occurs on thinner less fertile soils and consequently the vegetation is small and not very productive. It is good to get close to the ground to appreciate the fine detail and diversity of the grassland. Distinctive flowers that can be seen include common rock rose, wild thyme, horse shoe vetch, bird's foot trefoil, salad burnett, limestone bedstraw, devil's bit scabious, bloody cranesbill and fell wort.
Grassland areas require management to prevent the spread of scrub and trees which would turn the area into woodland. To do this the reserve is grazed during the winter. This allows plants to flower and set seed during the summer. Scrub is also cut by volunteers during organised work parties to assist sheep in their task.
Pack horse bridge built in the 15th century to cross Scandal Beck.
St Oswald's Church, Ravenstonedale.
The village of Ravenstonedale.
The Black Swan at Ravenstonedale.
British lambing season
Lambing can start as early as December in some parts of the country, but most farmers will begin in early spring. The sight of lambs scattering the fields is well known as a welcome sight, representing new beginnings and the end of a long winter.
When it comes to delivery, lots of ewes will deliver their offspring unassisted out in the field. But farmers are on hand night and day to keep a close eye in case there are any problems. Some ewes, especially first-time mums, will be brought into the lambing shed to give birth in case they need a helping hand.
How many lambs are born?
The number of lambs born by each ewe varies from breed to breed. First-time mums are more likely to give birth to one lamb, although twins are not uncommon. There are some breeds of sheep that average more than two lambs per litter.
But while lambing is an incredibly intense time in farming, the work starts well in advance. To ensure that their flock will cope with types of terrain or climate, or can produce a specific product, British farmers must carefully examine the characteristics of ewes and rams when preparing the breeding process, adding 'genetic expertise' to their broad list of skills.
Tupping
Ewes and rams mate in a process called tupping, which takes place in the autumn. But even before the rams are put to the ewes, lots of farmers are donning their match-maker hats to carefully pair their ewes and rams to create the best offspring. Farmers will use several rams to cover their flock, usually one ram for every 40 to 60 ewes. Using multiple rams increases the chance of ewes being covered by the rams within their fertile period and falling pregnant.
Ewes are only in season once per year, so unlike other animals that become fertile multiple times a year, there is a short time period for them to fall pregnant. There are expectations for breeds like the Polled Dorset, which can get pregnant all year round. Ultimately this is the reason that lambs being born is so intrinsically linked with spring and Easter time. Ewes will normally be two years old before they become a breeding sheep.
Like humans, ewes are scanned on farm to find out how many lambs they are carrying. The ideal number of lambs for a ewe to have differs depending on the farming system. Hill farmers prefer ewes to have just one lamb, while sheep in the lowland strive to have twins. It's not uncommon for ewes to have triplets, quads, or even quintuplets.
Pregnant ewes are often split up into groups at this stage so their feeding and nutrition can be carefully managed. A ewe carrying one lamb doesn't need the same amount of food as one carrying triplets.
Lambs are born around 145 days (4½ months) after the ewe falls pregnant. Lambing can start as early as December and go on to as late as June. Specialist breeds will lamb all year round, satisfying demand for the Christmas and Easter trade.
Depending on the type of farm and where it is, lambing can take place either indoors or outdoors. Often first-time mums will be brought inside to lamb so farmers can keep a close eye on them and give them a hand if needs be. This means that during lambing a farmer will be on hand all through the day and night to make sure things go smoothly.
Once the lamb is born, it's important it gets up on its feet quickly and latches to the ewe's teat to get the colostrum (first milk) which is packed with nutrients and antibodies. If this doesn't happen within the first few hours, the farmer will collect the colostrum from the mother and feed it directly to the lamb using a tube.
Unfortunately, lambing is a difficult time and not all ewes and lambs will survive, even in the best system. Farmers will pair up orphan lambs with other ewes for adoption. This happens in cases where the mother is unable to look after one of its lambs due to a multiple birth (triplets or quads), or if the ewe or lamb dies.
There are a few ways adoption can take place. Wet adoption is where the birthing fluid from a new born lamb is transferred to the adoptive lamb, so the ewe thinks it is her own. Dry adoption happens when a lamb has died. Skin is taken from the dead lamb and tied to the orphan so the adoptive mother will recognise the scent and take it as her own. Eventually the skin will fall off by which time the lamb and mother will have bonded.
Once the farmer is happy that the lamb is feeding well, they'll go out into the field which can be like a crèche with lots of other ewes and lambs running around. The ewes can graze on the fresh spring grass which helps them produce lots of milk for their hungry and growing lambs and can be supplemented with a sheep feed to make sure the milk is plentiful. Lambs might also be given special food called creep. It's put in lamb feeders which are too small for the mothers to get their nose into.
Lambs are fitted with identification ear tags which will stay on for the rest of their life. The lambs are normally weaned from their mothers between two and four months old when they will either go on to be breeding sheep (ewes or rams), or they'll be reared for meat. The ewes then have a few months to get into top condition, ready for Autumn tupping when the process starts all over again.
Visit https://www.countrysideonline.co.uk for more excellent British farming information.
Approaching a tunnel under the Carlisle to Settle Railway.
The track down to the River Eden.
Lammerside Castle, a 12th-century building which was rebuilt and strengthened in the 14th century as a Pele tower, to provide protection against Scots raiders.
Wharton Hall.
Podgill Viaduct.
The view from Podgill Viaduct.
Remains of a railway signal box.
Merrygill Viaduct.
The view from Merrygill Viaduct.
Hartley, just east of Kirkby Stephen.
Frank's Bridge, Kirkby Stephen.
The River Eden.
Kirkby Stephen.