/**
 * Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf), Loetz GmbH&Co.KG (Heidelberg)
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *         Florian Pirchner - Initial implementation
 */

package org.osbp.mysmartshop.dtos.mapper;

import java.util.Date;
import java.util.List;
import org.eclipse.osbp.dsl.dto.lib.MappingContext;
import org.osbp.mysmartshop.dtos.CashSlipDto;
import org.osbp.mysmartshop.dtos.McustomerDto;
import org.osbp.mysmartshop.dtos.mapper.BaseIDDtoMapper;
import org.osbp.mysmartshop.entities.CashSlip;
import org.osbp.mysmartshop.entities.Mcustomer;

/**
 * This class maps the dto {@link McustomerDto} to and from the entity {@link Mcustomer}.
 * 
 */
@SuppressWarnings("all")
public class McustomerDtoMapper<DTO extends McustomerDto, ENTITY extends Mcustomer> extends BaseIDDtoMapper<DTO, ENTITY> {
  /**
   * Creates a new instance of the entity
   */
  public Mcustomer createEntity() {
    return new Mcustomer();
  }
  
  /**
   * Creates a new instance of the dto
   */
  public McustomerDto createDto() {
    return new McustomerDto();
  }
  
  /**
   * Maps the entity {@link Mcustomer} to the dto {@link McustomerDto}.
   * 
   * @param dto - The target dto
   * @param entity - The source entity
   * @param context - The context to get information about depth,...
   * 
   */
  public void mapToDTO(final McustomerDto dto, final Mcustomer entity, final MappingContext context) {
    if(context == null){
    	throw new IllegalArgumentException("Please pass a context!");
    }
    context.register(createDtoHash(entity), dto);
    
    super.mapToDTO(dto, entity, context);
    
    dto.setAccount_num(toDto_account_num(entity, context));
    dto.setLname(toDto_lname(entity, context));
    dto.setFname(toDto_fname(entity, context));
    dto.setMi(toDto_mi(entity, context));
    dto.setAddress1(toDto_address1(entity, context));
    dto.setAddress2(toDto_address2(entity, context));
    dto.setAddress3(toDto_address3(entity, context));
    dto.setAddress4(toDto_address4(entity, context));
    dto.setCity(toDto_city(entity, context));
    dto.setState_province(toDto_state_province(entity, context));
    dto.setPostal_code(toDto_postal_code(entity, context));
    dto.setCountry(toDto_country(entity, context));
    dto.setPhone1(toDto_phone1(entity, context));
    dto.setPhone2(toDto_phone2(entity, context));
    dto.setBirthdate(toDto_birthdate(entity, context));
    dto.setMarital_status(toDto_marital_status(entity, context));
    dto.setYearly_income(toDto_yearly_income(entity, context));
    dto.setGender(toDto_gender(entity, context));
    dto.setTotal_children(toDto_total_children(entity, context));
    dto.setNum_children_at_home(toDto_num_children_at_home(entity, context));
    dto.setEducation(toDto_education(entity, context));
    dto.setDate_accnt_opened(toDto_date_accnt_opened(entity, context));
    dto.setMember_card(toDto_member_card(entity, context));
    dto.setOccupation(toDto_occupation(entity, context));
    dto.setHouseowner(toDto_houseowner(entity, context));
    dto.setNum_cars_owned(toDto_num_cars_owned(entity, context));
    dto.setFullname(toDto_fullname(entity, context));
    dto.setTest(toDto_test(entity, context));
    dto.setFoo(toDto_foo(entity, context));
  }
  
  /**
   * Maps the dto {@link McustomerDto} to the entity {@link Mcustomer}.
   * 
   * @param dto - The source dto
   * @param entity - The target entity
   * @param context - The context to get information about depth,...
   * 
   */
  public void mapToEntity(final McustomerDto dto, final Mcustomer entity, final MappingContext context) {
    if(context == null){
    	throw new IllegalArgumentException("Please pass a context!");
    }
    
    context.register(createEntityHash(dto), entity);
    context.registerMappingRoot(createEntityHash(dto), dto);
    super.mapToEntity(dto, entity, context);
    
    entity.setAccount_num(toEntity_account_num(dto, entity, context));
    entity.setLname(toEntity_lname(dto, entity, context));
    entity.setFname(toEntity_fname(dto, entity, context));
    entity.setMi(toEntity_mi(dto, entity, context));
    entity.setAddress1(toEntity_address1(dto, entity, context));
    entity.setAddress2(toEntity_address2(dto, entity, context));
    entity.setAddress3(toEntity_address3(dto, entity, context));
    entity.setAddress4(toEntity_address4(dto, entity, context));
    entity.setCity(toEntity_city(dto, entity, context));
    entity.setState_province(toEntity_state_province(dto, entity, context));
    entity.setPostal_code(toEntity_postal_code(dto, entity, context));
    entity.setCountry(toEntity_country(dto, entity, context));
    entity.setPhone1(toEntity_phone1(dto, entity, context));
    entity.setPhone2(toEntity_phone2(dto, entity, context));
    entity.setBirthdate(toEntity_birthdate(dto, entity, context));
    entity.setMarital_status(toEntity_marital_status(dto, entity, context));
    entity.setYearly_income(toEntity_yearly_income(dto, entity, context));
    entity.setGender(toEntity_gender(dto, entity, context));
    entity.setTotal_children(toEntity_total_children(dto, entity, context));
    entity.setNum_children_at_home(toEntity_num_children_at_home(dto, entity, context));
    entity.setEducation(toEntity_education(dto, entity, context));
    entity.setDate_accnt_opened(toEntity_date_accnt_opened(dto, entity, context));
    entity.setMember_card(toEntity_member_card(dto, entity, context));
    entity.setOccupation(toEntity_occupation(dto, entity, context));
    entity.setHouseowner(toEntity_houseowner(dto, entity, context));
    entity.setNum_cars_owned(toEntity_num_cars_owned(dto, entity, context));
    entity.setFullname(toEntity_fullname(dto, entity, context));
    entity.setTest(toEntity_test(dto, entity, context));
    toEntity_slips(dto, entity, context);
  }
  
  /**
   * Maps the property account_num from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected long toDto_account_num(final Mcustomer in, final MappingContext context) {
    return in.getAccount_num();
  }
  
  /**
   * Maps the property account_num from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected long toEntity_account_num(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getAccount_num();
  }
  
  /**
   * Maps the property lname from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toDto_lname(final Mcustomer in, final MappingContext context) {
    return in.getLname();
  }
  
  /**
   * Maps the property lname from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toEntity_lname(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getLname();
  }
  
  /**
   * Maps the property fname from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toDto_fname(final Mcustomer in, final MappingContext context) {
    return in.getFname();
  }
  
  /**
   * Maps the property fname from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toEntity_fname(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getFname();
  }
  
  /**
   * Maps the property mi from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toDto_mi(final Mcustomer in, final MappingContext context) {
    return in.getMi();
  }
  
  /**
   * Maps the property mi from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toEntity_mi(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getMi();
  }
  
  /**
   * Maps the property address1 from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toDto_address1(final Mcustomer in, final MappingContext context) {
    return in.getAddress1();
  }
  
  /**
   * Maps the property address1 from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toEntity_address1(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getAddress1();
  }
  
  /**
   * Maps the property address2 from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toDto_address2(final Mcustomer in, final MappingContext context) {
    return in.getAddress2();
  }
  
  /**
   * Maps the property address2 from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toEntity_address2(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getAddress2();
  }
  
  /**
   * Maps the property address3 from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toDto_address3(final Mcustomer in, final MappingContext context) {
    return in.getAddress3();
  }
  
  /**
   * Maps the property address3 from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toEntity_address3(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getAddress3();
  }
  
  /**
   * Maps the property address4 from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toDto_address4(final Mcustomer in, final MappingContext context) {
    return in.getAddress4();
  }
  
  /**
   * Maps the property address4 from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toEntity_address4(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getAddress4();
  }
  
  /**
   * Maps the property city from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toDto_city(final Mcustomer in, final MappingContext context) {
    return in.getCity();
  }
  
  /**
   * Maps the property city from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toEntity_city(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getCity();
  }
  
  /**
   * Maps the property state_province from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toDto_state_province(final Mcustomer in, final MappingContext context) {
    return in.getState_province();
  }
  
  /**
   * Maps the property state_province from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toEntity_state_province(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getState_province();
  }
  
  /**
   * Maps the property postal_code from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toDto_postal_code(final Mcustomer in, final MappingContext context) {
    return in.getPostal_code();
  }
  
  /**
   * Maps the property postal_code from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toEntity_postal_code(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getPostal_code();
  }
  
  /**
   * Maps the property country from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toDto_country(final Mcustomer in, final MappingContext context) {
    return in.getCountry();
  }
  
  /**
   * Maps the property country from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toEntity_country(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getCountry();
  }
  
  /**
   * Maps the property phone1 from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toDto_phone1(final Mcustomer in, final MappingContext context) {
    return in.getPhone1();
  }
  
  /**
   * Maps the property phone1 from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toEntity_phone1(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getPhone1();
  }
  
  /**
   * Maps the property phone2 from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toDto_phone2(final Mcustomer in, final MappingContext context) {
    return in.getPhone2();
  }
  
  /**
   * Maps the property phone2 from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toEntity_phone2(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getPhone2();
  }
  
  /**
   * Maps the property birthdate from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected Date toDto_birthdate(final Mcustomer in, final MappingContext context) {
    return in.getBirthdate();
  }
  
  /**
   * Maps the property birthdate from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected Date toEntity_birthdate(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getBirthdate();
  }
  
  /**
   * Maps the property marital_status from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toDto_marital_status(final Mcustomer in, final MappingContext context) {
    return in.getMarital_status();
  }
  
  /**
   * Maps the property marital_status from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toEntity_marital_status(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getMarital_status();
  }
  
  /**
   * Maps the property yearly_income from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toDto_yearly_income(final Mcustomer in, final MappingContext context) {
    return in.getYearly_income();
  }
  
  /**
   * Maps the property yearly_income from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toEntity_yearly_income(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getYearly_income();
  }
  
  /**
   * Maps the property gender from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toDto_gender(final Mcustomer in, final MappingContext context) {
    return in.getGender();
  }
  
  /**
   * Maps the property gender from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toEntity_gender(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getGender();
  }
  
  /**
   * Maps the property total_children from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected int toDto_total_children(final Mcustomer in, final MappingContext context) {
    return in.getTotal_children();
  }
  
  /**
   * Maps the property total_children from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected int toEntity_total_children(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getTotal_children();
  }
  
  /**
   * Maps the property num_children_at_home from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected int toDto_num_children_at_home(final Mcustomer in, final MappingContext context) {
    return in.getNum_children_at_home();
  }
  
  /**
   * Maps the property num_children_at_home from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected int toEntity_num_children_at_home(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getNum_children_at_home();
  }
  
  /**
   * Maps the property education from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toDto_education(final Mcustomer in, final MappingContext context) {
    return in.getEducation();
  }
  
  /**
   * Maps the property education from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toEntity_education(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getEducation();
  }
  
  /**
   * Maps the property date_accnt_opened from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toDto_date_accnt_opened(final Mcustomer in, final MappingContext context) {
    return in.getDate_accnt_opened();
  }
  
  /**
   * Maps the property date_accnt_opened from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toEntity_date_accnt_opened(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getDate_accnt_opened();
  }
  
  /**
   * Maps the property member_card from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toDto_member_card(final Mcustomer in, final MappingContext context) {
    return in.getMember_card();
  }
  
  /**
   * Maps the property member_card from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toEntity_member_card(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getMember_card();
  }
  
  /**
   * Maps the property occupation from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toDto_occupation(final Mcustomer in, final MappingContext context) {
    return in.getOccupation();
  }
  
  /**
   * Maps the property occupation from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toEntity_occupation(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getOccupation();
  }
  
  /**
   * Maps the property houseowner from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toDto_houseowner(final Mcustomer in, final MappingContext context) {
    return in.getHouseowner();
  }
  
  /**
   * Maps the property houseowner from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toEntity_houseowner(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getHouseowner();
  }
  
  /**
   * Maps the property num_cars_owned from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected int toDto_num_cars_owned(final Mcustomer in, final MappingContext context) {
    return in.getNum_cars_owned();
  }
  
  /**
   * Maps the property num_cars_owned from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected int toEntity_num_cars_owned(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getNum_cars_owned();
  }
  
  /**
   * Maps the property fullname from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toDto_fullname(final Mcustomer in, final MappingContext context) {
    return in.getFullname();
  }
  
  /**
   * Maps the property fullname from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toEntity_fullname(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getFullname();
  }
  
  /**
   * Maps the property test from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toDto_test(final Mcustomer in, final MappingContext context) {
    return in.getTest();
  }
  
  /**
   * Maps the property test from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toEntity_test(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getTest();
  }
  
  /**
   * Maps the property slips from the given entity to the dto.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return A list of mapped dtos
   * 
   */
  protected List<CashSlipDto> toDto_slips(final Mcustomer in, final MappingContext context) {
    // nothing to do here. Mapping is done by OppositeLists
    return null;
  }
  
  /**
   * Maps the property slips from the given dto to the entity.
   * 
   * @param in - The source dto
   * @param parentEntity - The parent entity
   * @param context - The context to get information about depth,...
   * @return A list of mapped entities
   * 
   */
  protected List<CashSlip> toEntity_slips(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    org.eclipse.osbp.dsl.dto.lib.IMapper<CashSlipDto, CashSlip> mapper = getToEntityMapper(CashSlipDto.class, CashSlip.class);
    if(mapper == null) {
    	throw new IllegalStateException("Mapper must not be null!");
    }
    
    org.eclipse.osbp.dsl.dto.lib.IEntityMappingList<CashSlipDto> childsList = 
    	(org.eclipse.osbp.dsl.dto.lib.IEntityMappingList<CashSlipDto>) in.internalGetSlips();
    
    // if entities are being added, then they are passed to
    // #addToContainerChilds of the parent entity. So the container ref is setup
    // properly!
    // if entities are being removed, then they are passed to the
    // #internalRemoveFromChilds method of the parent entity. So they are
    // removed directly from the list of entities.
    childsList.mapToEntity(mapper,
    		parentEntity::addToSlips,
    		parentEntity::internalRemoveFromSlips);
    return null;
  }
  
  /**
   * Maps the property foo from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toDto_foo(final Mcustomer in, final MappingContext context) {
    return in.getFoo();
  }
  
  /**
   * Maps the property foo from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toEntity_foo(final McustomerDto in, final Mcustomer parentEntity, final MappingContext context) {
    return in.getFoo();
  }
  
  public String createDtoHash(final Object in) {
    return org.eclipse.osbp.runtime.common.hash.HashUtil.createObjectWithIdHash(McustomerDto.class, in);
  }
  
  public String createEntityHash(final Object in) {
    return org.eclipse.osbp.runtime.common.hash.HashUtil.createObjectWithIdHash(Mcustomer.class, in);
  }
}
