/**
 * Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 * 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.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.emf.databinding.EMFProperties;
import org.eclipse.osbp.ecview.core.common.editpart.IConverterEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.IElementEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.emf.ElementEditpart;
import org.eclipse.osbp.ecview.core.common.filter.IFilterablePresentation;
import org.eclipse.osbp.ecview.core.common.filter.IRefreshRowsPresentation;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableCollectionEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableMultiSelectionEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableSelectionEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YFlatAlignment;
import org.eclipse.osbp.ecview.core.common.model.datatypes.YDatadescription;
import org.eclipse.osbp.ecview.core.common.presentation.DelegatingConverterFactory;
import org.eclipse.osbp.ecview.core.databinding.emf.model.ECViewModelBindable;
import org.eclipse.osbp.ecview.core.extension.model.extension.ExtensionModelPackage;
import org.eclipse.osbp.ecview.core.extension.model.extension.YColumn;
import org.eclipse.osbp.ecview.core.extension.model.extension.YSelectionType;
import org.eclipse.osbp.ecview.core.extension.model.extension.YSortColumn;
import org.eclipse.osbp.ecview.core.extension.model.extension.YTable;
import org.eclipse.osbp.ecview.core.ui.core.editparts.extension.ITableEditpart;
import org.eclipse.osbp.runtime.common.annotations.DtoUtils;
import org.eclipse.osbp.runtime.common.annotations.PropertiesUtil;
import org.eclipse.osbp.runtime.common.i18n.I18nUtil;
import org.eclipse.osbp.runtime.common.i18n.II18nService;
import org.eclipse.osbp.runtime.common.state.ISharedStateContext;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractFieldWidgetPresenter;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal.util.Util;
import org.eclipse.osbp.runtime.web.vaadin.common.converter.StringToFormattedNumberConverter;
import org.eclipse.osbp.runtime.web.vaadin.common.data.BeanServiceLazyLoadingContainer;
import org.eclipse.osbp.runtime.web.vaadin.common.data.DeepResolvingBeanItemContainer;
import org.eclipse.osbp.runtime.web.vaadin.common.data.IBeanSearchService;
import org.eclipse.osbp.runtime.web.vaadin.common.data.IBeanSearchServiceFactory;
import org.eclipse.osbp.runtime.web.vaadin.common.data.ILazyRefreshFilterable;
import org.eclipse.osbp.runtime.web.vaadin.common.data.INestedPropertyAble;
import org.eclipse.osbp.runtime.web.vaadin.common.resource.IResourceProvider;

import com.vaadin.data.Container;
import com.vaadin.data.Container.Filter;
import com.vaadin.data.Container.Filterable;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.data.util.ObjectProperty;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.data.util.converter.ConverterUtil;
import com.vaadin.server.ErrorMessage;
import com.vaadin.server.Resource;
import com.vaadin.server.ThemeResource;
import com.vaadin.ui.AbstractSelect.ItemCaptionMode;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.ComponentContainer;
import com.vaadin.ui.Field;
import com.vaadin.ui.Table;
import com.vaadin.ui.Table.Align;
import com.vaadin.ui.Table.RowHeaderMode;
import com.vaadin.ui.UI;

// TODO: Auto-generated Javadoc
/**
 * This presenter is responsible to render a table on the given layout.
 */
@SuppressWarnings("restriction")
public class TablePresentation extends AbstractFieldWidgetPresenter<Component>
		implements IFilterablePresentation, IRefreshRowsPresentation {

	/** The model access. */
	private final ModelAccess modelAccess;

	/** The table. */
	private Table table;

	/** The property. */
	@SuppressWarnings("rawtypes")
	private ObjectProperty property;

	/** The apply columns. */
	private boolean applyColumns;

	private boolean containerReadonly;

	/**
	 * Constructor.
	 * 
	 * @param editpart
	 *            The editpart of that presenter
	 */
	public TablePresentation(IElementEditpart editpart) {
		super((ITableEditpart) editpart);
		this.modelAccess = new ModelAccess((YTable) editpart.getModel());
	}

	/**
	 * {@inheritDoc}
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public Component doCreateWidget(Object parent) {
		if (table == null) {

			table = new CustomTable();
			table.addStyleName(CSS_CLASS_CONTROL);
			table.setMultiSelect(modelAccess.yField.getSelectionType() == YSelectionType.MULTI);
			table.setSelectable(true);
			table.setImmediate(true);
			setupComponent(table, getCastedModel());

			associateWidget(table, modelAccess.yField);
			if (modelAccess.isCssIdValid()) {
				table.setId(modelAccess.getCssID());
			} else {
				table.setId(getEditpart().getId());
			}

			if (table.isMultiSelect()) {
				property = new ObjectProperty(new HashSet(), Set.class);
			} else {
				if (modelAccess.yField.getType() != null) {
					property = new ObjectProperty(null,
							modelAccess.yField.getType());
				} else {
					property = new ObjectProperty(null, Object.class);
				}
			}
			table.setPropertyDataSource(property);

			applyColumns = false;
			if (modelAccess.yField.getType() == String.class) {
				IndexedContainer datasource = new IndexedContainer();
				table.setContainerDataSource(datasource);
				table.setItemCaptionMode(ItemCaptionMode.ID);
			} else {
				if (modelAccess.yField.getType() != null) {
					IBeanSearchService<?> service = null;
					IBeanSearchServiceFactory factory = getViewContext()
							.getService(
									IBeanSearchServiceFactory.class.getName());
					if (factory != null) {
						service = factory.createService(modelAccess.yField
								.getType());
					}
					if (modelAccess.yField.isUseBeanService()
							&& service != null) {
						ISharedStateContext sharedState = getViewContext()
								.getService(ISharedStateContext.class.getName());
						BeanServiceLazyLoadingContainer<?> datasource = new BeanServiceLazyLoadingContainer(
								service, modelAccess.yField.getType(),
								sharedState);
						table.setContainerDataSource(datasource);
						containerReadonly = true;
					} else {
						DeepResolvingBeanItemContainer datasource = new DeepResolvingBeanItemContainer(
								modelAccess.yField.getType());
						table.setContainerDataSource(datasource);
					}
					applyColumns = true;
				} else {
					IndexedContainer container = new IndexedContainer();
					container.addContainerProperty("for", String.class, null);
					container.addContainerProperty("preview", String.class,
							null);
					container.addItem(new String[] { "Some value", "other" });
					table.setContainerDataSource(container);
				}
			}

			String itemImageProperty = modelAccess.yField
					.getItemImageProperty();
			if (itemImageProperty != null && !itemImageProperty.equals("")) {
				table.setItemIconPropertyId(itemImageProperty);
				table.setRowHeaderMode(RowHeaderMode.EXPLICIT);
			}

			// creates the binding for the field
			createBindings(modelAccess.yField, table);

			if (modelAccess.isCssClassValid()) {
				table.addStyleName(modelAccess.getCssClass());
			}

			applyCaptions();

			initializeField(table);
		}
		return table;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.ecview.core.common.filter.IRefreshRowsPresentation#
	 * refreshRows()
	 */
	@Override
	public void refreshRows() {
		if (isRendered()) {
			table.refreshRowCache();
		}
	}

	/**
	 * Applies the column setting to the table.
	 */
	@SuppressWarnings({ "serial", "unchecked" })
	protected void applyColumns() {
		Class<?> type = modelAccess.yField.getType();

		// set the visible columns and icons
		List<String> columns = new ArrayList<String>();
		Collection<?> propertyIds = table.getContainerDataSource()
				.getContainerPropertyIds();

		if (!modelAccess.yField.getColumns().isEmpty()) {
			for (YColumn yColumn : modelAccess.yField.getColumns()) {
				if (yColumn.isVisible()
						&& propertyIds.contains(yColumn.getPropertyPath())
						|| isNestedColumn(yColumn)) {
					columns.add(yColumn.getPropertyPath());
				}
			}

			// add nested properties
			if (table.getContainerDataSource() instanceof INestedPropertyAble) {
				INestedPropertyAble<?> container = (INestedPropertyAble<?>) table
						.getContainerDataSource();
				for (String property : columns) {
					if (property.contains(".")) {
						container.addNestedContainerProperty(property);
					}
				}
			}

			table.setVisibleColumns(columns.toArray(new Object[columns.size()]));
			table.setColumnCollapsingAllowed(true);

			II18nService i18nService = getViewContext().getService(
					II18nService.class.getName());
			IResourceProvider resourceProvider = (IResourceProvider) getViewContext()
					.getService(IResourceProvider.class.getName());
			// traverse the columns again and set other properties
			for (YColumn yColumn : modelAccess.yField.getColumns()) {
				if (yColumn.isVisible()
						&& (propertyIds.contains(yColumn.getPropertyPath()) || isNestedColumn(yColumn))) {
					String columnId = yColumn.getPropertyPath();

					table.setColumnHeader(columnId, getColumnHeader(yColumn));
					table.setColumnAlignment(columnId,
							toAlign(yColumn.getAlignment()));
					table.setColumnCollapsed(columnId, yColumn.isCollapsed());
					table.setColumnCollapsible(columnId,
							yColumn.isCollapsible());
					if (yColumn.getExpandRatio() >= 0) {
						table.setColumnExpandRatio(columnId,
								yColumn.getExpandRatio());
					}
					// Boolean check to display a checkbox instead of the
					// boolean value as String.
					if (yColumn.getType() == Boolean.class) {
						// check to avoid an IllegalArgumentException adding an
						// already existing ColumnGenerator.
						if (table.getColumnGenerator(columnId) == null) {
							table.addGeneratedColumn(columnId,
									new Table.ColumnGenerator() {
										public Component generateCell(
												Table source, Object itemId,
												Object columnId) {
											Item item = table.getItem(itemId);
											CheckBox box = new CheckBox();
											box.setEnabled(false);
											Boolean value = (Boolean) item
													.getItemProperty(columnId)
													.getValue();
											box.setValue(value);
											return box;
										}
									});
						}
					}
					// --------------
					if (yColumn.getIcon() != null
							&& !yColumn.getIcon().equals("")) {
						if (i18nService != null) {
							String translation = i18nService.getValue(yColumn
									.getIcon(), UI.getCurrent().getLocale());
							if (translation != null && !translation.equals("")) {
								Resource icon = resourceProvider
										.getResource(translation);
								if (icon != null) {
									table.setColumnIcon(columnId, icon);
								}
							}
						} else {
							table.setColumnIcon(columnId, resourceProvider
									.getResource(yColumn.getIcon()));
						}
					}
				}
			}

			// apply the converters
			//
			for (YColumn yColumn : modelAccess.yField.getColumns()) {
				if (yColumn.getConverter() == null) {
					// try to derive the converter from the datatype property at
					// field level
					String columnId = yColumn.getPropertyPath();
					Class<?> resultClass = table.getContainerDataSource()
							.getType(columnId);
					if (Number.class.isAssignableFrom(resultClass)
							&& PropertiesUtil.hasKey(type, columnId,
									"decimalformat")) {
						String format = PropertiesUtil.getValue(type, columnId,
								"decimalformat");
						if (format != null && !format.isEmpty()) {
							table.setConverter(
									columnId,
									new StringToFormattedNumberConverter(
											format,
											(Class<? extends Number>) resultClass));
						}
					}
				} else {
					@SuppressWarnings("rawtypes")
					Converter converter = (Converter) DelegatingConverterFactory
							.getInstance().createConverter(
									getViewContext(),
									(IConverterEditpart) ElementEditpart
											.getEditpart(getViewContext(),
													yColumn.getConverter()));
					if (converter != null) {
						String columnId = yColumn.getPropertyPath();
						table.setConverter(columnId, converter);
					}
				}
			}
		}

		// apply the sort order
		applySortOrder();

		applyCellStyles();

		// apply the dirty flag
		// applyDirtyFlag(type);
	}

	@SuppressWarnings("serial")
	protected void applyCellStyles() {
		table.setCellStyleGenerator(new Table.CellStyleGenerator() {

			@Override
			public String getStyle(Table source, Object itemId,
					Object propertyId) {
				if (itemId == null || propertyId == null) {
					return "";
				}
				if (Number.class.isAssignableFrom(source
						.getContainerDataSource().getType(propertyId))) {
					return " v-align-right";
				}
				return "";
			}
		});
	}

	// protected void applyDirtyFlag(Class<?> type) {
	// final String dirtyProperty = getDirtyProperty(type);
	// // if a dirty property is available, we use it
	// if (dirtyProperty != null) {
	// table.setCellStyleGenerator(new Table.CellStyleGenerator() {
	// private static final long serialVersionUID = -2462674164411654020L;
	// @Override
	// public String getStyle(Table source, Object itemId,
	// Object propertyId) {
	// if (propertyId == null) {
	// return null;
	// }
	// if (propertyId.equals(dirtyProperty)) {
	// try {
	// boolean dirty = DtoUtils.invokeDirtyGetter(itemId);
	// return dirty ? "dirty" : null;
	// } catch (IllegalAccessException e) {
	// }
	// } else {
	// Class<?> propertyType = source.getContainerDataSource()
	// .getType(propertyId);
	// if (Number.class.isAssignableFrom(propertyType)) {
	// return "v-align-right";
	// }
	// }
	// }
	// table.setCellStyleGenerator(new Table.CellStyleGenerator() {
	// @Override
	// public String getStyle(Table source, Object itemId,
	// Object propertyId) {
	// if (propertyId == null) {
	// return null;
	// }
	// });
	// }

	protected void applySortOrder() {
		if (!modelAccess.yField.getSortOrder().isEmpty()
				&& table.getContainerDataSource() instanceof Container.Sortable) {
			List<String> sortCol = new ArrayList<>();
			List<Boolean> sortDirection = new ArrayList<>();
			for (YSortColumn yColumn : modelAccess.yField.getSortOrder()) {
				// add the nested sort columns to the container
				if (isNestedColumn(yColumn)) {
					if (table.getContainerDataSource() instanceof INestedPropertyAble) {
						INestedPropertyAble<?> container = (INestedPropertyAble<?>) table
								.getContainerDataSource();
						container.addNestedContainerProperty(yColumn
								.getPropertyPath());
					}
				}

				sortCol.add(yColumn.getPropertyPath());
				sortDirection.add(yColumn.isAsc());
			}
			Container.Sortable sortable = (Container.Sortable) table
					.getContainerDataSource();

			boolean[] asc = new boolean[sortDirection.size()];
			for (int i = 0; i < sortDirection.size(); i++) {
				asc[i] = sortDirection.get(i);
			}

			sortable.sort(sortCol.toArray(new String[sortCol.size()]), asc);

			if (!sortCol.isEmpty()) {
				table.setSortContainerPropertyId(sortCol.get(0));
				table.setSortAscending(asc[0]);
			}
		}
	}

	/**
	 * Gets the dirty property.
	 *
	 * @param type
	 *            the type
	 * @return the dirty property
	 */
	protected String getDirtyProperty(Class<?> type) {
		String temp = null;
		java.lang.reflect.Field dirtyField = DtoUtils.getDirtyField(type);
		if (dirtyField != null) {
			temp = dirtyField.getName();
		}
		return temp;
	}

	/**
	 * Checks if is nested column.
	 *
	 * @param yColumn
	 *            the y column
	 * @return true, if is nested column
	 */
	protected boolean isNestedColumn(YColumn yColumn) {
		return yColumn.getPropertyPath() != null
				&& yColumn.getPropertyPath().contains(".");
	}

	/**
	 * Checks if is nested column.
	 *
	 * @param yColumn
	 *            the y column
	 * @return true, if is nested column
	 */
	protected boolean isNestedColumn(YSortColumn yColumn) {
		return yColumn.getPropertyPath() != null
				&& yColumn.getPropertyPath().contains(".");
	}

	/**
	 * Returns the column header.
	 *
	 * @param yColumn
	 *            the y column
	 * @return the column header
	 */
	private String getColumnHeader(YColumn yColumn) {
		YDatadescription yDt = yColumn.getDatadescription();
		if (yDt == null) {
			return yColumn.getPropertyPath();
		}

		String result = null;
		II18nService service = getI18nService();
		if (service != null && yDt.getLabelI18nKey() != null) {
			result = service.getValue(yDt.getLabelI18nKey(), getLocale());
		}

		if (result == null || result.equals("")) {
			result = yDt.getLabel();
		}

		if (result == null || result.equals("")) {
			result = yColumn.getPropertyPath();
		}

		return result;
	}

	/**
	 * To align.
	 *
	 * @param alignment
	 *            the alignment
	 * @return the align
	 */
	private Align toAlign(YFlatAlignment alignment) {
		switch (alignment) {
		case LEFT:
			return Align.LEFT;
		case CENTER:
			return Align.CENTER;
		case RIGHT:
			return Align.RIGHT;
		}
		return Align.LEFT;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.
	 * AbstractVaadinWidgetPresenter#doUpdateLocale(java.util.Locale)
	 */
	@Override
	protected void doUpdateLocale(Locale locale) {
		// no need to set the locale to the ui elements. Is handled by vaadin
		// internally.

		// update the captions
		applyCaptions();
	}

	/**
	 * Applies the labels to the widgets.
	 */
	protected void applyCaptions() {

		// applies the column properties
		if (applyColumns) {
			applyColumns();
		}

		Util.applyCaptions(getI18nService(), modelAccess.getLabel(),
				modelAccess.getLabelI18nKey(), getLocale(), table);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.ecview.core.common.filter.IFilterablePresentation#
	 * applyFilter(java.lang.Object)
	 */
	@Override
	public void applyFilter(Object filter) {
		Container container = table.getContainerDataSource();
		if (container instanceof Container.Filterable) {
			Container.Filterable filterable = (Filterable) container;
			filterable.removeAllContainerFilters();
			if (filter != null) {
				filterable.addContainerFilter((Filter) filter);
			} else {
				if (container instanceof ILazyRefreshFilterable) {
					ILazyRefreshFilterable lazyFilterable = (ILazyRefreshFilterable) container;
					lazyFilterable.refreshFilters();
				}
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.
	 * AbstractFieldWidgetPresenter#doGetField()
	 */
	@Override
	protected Field<?> doGetField() {
		return table;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.
	 * AbstractVaadinWidgetPresenter
	 * #internalGetObservableEndpoint(org.eclipse.osbp
	 * .ecview.core.common.model.core.YEmbeddableBindingEndpoint)
	 */
	@Override
	protected IObservable internalGetObservableEndpoint(
			YEmbeddableBindingEndpoint bindableValue) {
		if (bindableValue == null) {
			throw new IllegalArgumentException(
					"BindableValue must not be null!");
		}

		if (bindableValue instanceof YEmbeddableCollectionEndpoint) {
			return internalGetCollectionEndpoint();
		} else if (bindableValue instanceof YEmbeddableSelectionEndpoint) {
			return internalGetSelectionEndpoint((YEmbeddableSelectionEndpoint) bindableValue);
		} else if (bindableValue instanceof YEmbeddableMultiSelectionEndpoint) {
			return internalGetMultiSelectionEndpoint();
		}
		throw new IllegalArgumentException("Not a valid input: "
				+ bindableValue);
	}

	/**
	 * Returns the observable to observe the collection.
	 *
	 * @return the i observable list
	 */
	protected IObservableList internalGetCollectionEndpoint() {
		// return the observable value for text
		return EMFProperties.list(
				ExtensionModelPackage.Literals.YTABLE__COLLECTION).observe(
				getModel());
	}

	/**
	 * Returns the observable to observe the selection.
	 *
	 * @param yEndpoint
	 *            the y endpoint
	 * @return the i observable value
	 */
	protected IObservableValue internalGetSelectionEndpoint(
			YEmbeddableSelectionEndpoint yEndpoint) {

		String attributePath = ECViewModelBindable.getAttributePath(
				ExtensionModelPackage.Literals.YTABLE__SELECTION,
				yEndpoint.getAttributePath());

		// return the observable value for text
		return ECViewModelBindable.observeValue(castEObject(getModel()),
				attributePath, modelAccess.yField.getType(),
				modelAccess.yField.getEmfNsURI());
	}

	/**
	 * Returns the observable to observe the selection.
	 *
	 * @return the i observable list
	 */
	protected IObservableList internalGetMultiSelectionEndpoint() {
		// return the observable value for text
		return EMFProperties.list(
				ExtensionModelPackage.Literals.YTABLE__MULTI_SELECTION)
				.observe(getModel());
	}

	/**
	 * Creates the bindings for the given values.
	 *
	 * @param yField
	 *            the y field
	 * @param field
	 *            the field
	 */
	protected void createBindings(YTable yField, Table field) {
		// create the model binding from ridget to ECView-model
		registerBinding(createBindingsContainerContents(
				castEObject(getModel()),
				ExtensionModelPackage.Literals.YTABLE__COLLECTION, field,
				yField.getType(), containerReadonly));

		// create the model binding from ridget to ECView-model
		if (modelAccess.yField.getSelectionType() == YSelectionType.MULTI) {
			// create the model binding from ridget to ECView-model
			registerBinding(createBindingsMultiSelection(
					castEObject(getModel()),
					ExtensionModelPackage.Literals.YTABLE__MULTI_SELECTION,
					field, yField.getType()));
		} else {
			// create the model binding from ridget to ECView-model
			registerBinding(createBindingsSelection(castEObject(getModel()),
					ExtensionModelPackage.Literals.YTABLE__SELECTION, field,
					yField.getType()));

		}

		super.createBindings(yField, field, null);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#
	 * getWidget()
	 */
	@Override
	public Component getWidget() {
		return table;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#
	 * isRendered()
	 */
	@Override
	public boolean isRendered() {
		return table != null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void doUnrender() {
		if (table != null) {

			// unbind all active bindings
			unbind();

			Component parent = ((Component) table.getParent());
			if (parent != null && parent instanceof ComponentContainer) {
				((ComponentContainer) parent).removeComponent(table);
			}

			// remove assocations
			unassociateWidget(table);

			table = null;
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected void internalDispose() {
		try {
			unrender();
		} finally {
			super.internalDispose();
		}
	}

	/**
	 * A helper class.
	 */
	private static class ModelAccess {

		/** The y field. */
		private final YTable yField;

		/**
		 * Instantiates a new model access.
		 *
		 * @param yField
		 *            the y field
		 */
		public ModelAccess(YTable yField) {
			super();
			this.yField = yField;
		}

		/**
		 * Gets the css class.
		 *
		 * @return the css class
		 * @see org.eclipse.osbp.ecview.core.ui.core.model.core.YCssAble#getCssClass()
		 */
		public String getCssClass() {
			return yField.getCssClass();
		}

		/**
		 * Returns true, if the css class is not null and not empty.
		 *
		 * @return true, if is css class valid
		 */
		public boolean isCssClassValid() {
			return getCssClass() != null && !getCssClass().equals("");
		}

		/**
		 * Gets the css id.
		 *
		 * @return the css id
		 * @see org.eclipse.osbp.ecview.core.ui.core.model.core.YCssAble#getCssID()
		 */
		public String getCssID() {
			return yField.getCssID();
		}

		/**
		 * Returns true, if the css id is not null and not empty.
		 *
		 * @return true, if is css id valid
		 */
		public boolean isCssIdValid() {
			return getCssID() != null && !getCssID().equals("");
		}

		/**
		 * Returns the label.
		 *
		 * @return the label
		 */
		public String getLabel() {
			return yField.getDatadescription() != null ? yField
					.getDatadescription().getLabel() : null;
		}

		/**
		 * Returns the label.
		 *
		 * @return the label i18n key
		 */
		public String getLabelI18nKey() {
			return yField.getDatadescription() != null ? yField
					.getDatadescription().getLabelI18nKey() : null;
		}
	}

	/**
	 * Converts the string value of the item icon property to
	 * {@link ThemeResource}.
	 */
	@SuppressWarnings("serial")
	private class CustomTable extends Table {

		/** The item icon property id. */
		private Object itemIconPropertyId;

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.vaadin.ui.AbstractSelect#setItemIconPropertyId(java.lang.Object)
		 */
		@Override
		public void setItemIconPropertyId(Object propertyId)
				throws IllegalArgumentException {
			if (propertyId == null) {
				super.setItemIconPropertyId(propertyId);
			} else if (!getContainerPropertyIds().contains(propertyId)) {
				// super.setItemIconPropertyId(propertyId);
			} else if (String.class.isAssignableFrom(getType(propertyId))) {
				itemIconPropertyId = propertyId;
			} else {
				super.setItemIconPropertyId(propertyId);
			}
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.vaadin.ui.AbstractSelect#getItemIconPropertyId()
		 */
		public Object getItemIconPropertyId() {
			return itemIconPropertyId != null ? itemIconPropertyId : super
					.getItemIconPropertyId();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.vaadin.ui.AbstractSelect#getItemIcon(java.lang.Object)
		 */
		public Resource getItemIcon(Object itemId) {
			if (itemIconPropertyId == null) {
				return super.getItemIcon(itemId);
			} else {
				final Property<?> ip = getContainerProperty(itemId,
						getItemIconPropertyId());
				if (ip == null) {
					return null;
				}
				final Object icon = ip.getValue();
				if (icon instanceof String) {
					return new ThemeResource((String) icon);
				}
			}
			return null;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.vaadin.ui.Table#formatPropertyValue(java.lang.Object,
		 * java.lang.Object, com.vaadin.data.Property)
		 */
		@SuppressWarnings({ "unchecked", "rawtypes" })
		protected String formatPropertyValue(Object rowId, Object colId,
				Property<?> property) {
			if (property == null) {
				return "";
			}
			Converter<String, Object> converter = null;

			if (hasConverter(colId)) {
				converter = getConverter(colId);
			} else {
				converter = (Converter) ConverterUtil.getConverter(
						String.class, property.getType(), getSession());
			}
			Object value = property.getValue();
			if (converter != null) {
				return converter.convertToPresentation(value, String.class,
						getLocale());
			} else {
				if (value instanceof Enum<?>) {
					return I18nUtil.translateEnum(getI18nService(), value,
							getLocale());
				} else if (value instanceof Boolean) {
					return I18nUtil.translateBoolean(getI18nService(),
							(Boolean) value, getLocale());
				} else if (value instanceof Number) {
					return I18nUtil.translateNumber(getI18nService(),
							(Number) value, getLocale());
				}
			}
			return (null != value) ? value.toString() : "";
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.vaadin.ui.AbstractField#getErrorMessage()
		 */
		@Override
		public ErrorMessage getErrorMessage() {
			if (isDisposed()) {
				// after disposal, Vaadin will call this method once.
				return null;
			}

			ErrorMessage message = super.getErrorMessage();
			reportValidationError(message);
			return message;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.vaadin.ui.AbstractField#focus()
		 */
		@Override
		public void focus() {
			super.focus();

			setValue(getCurrentPageFirstItemId());
		}
	}
}
