/*
 * Copyright (c) 2010-2013, 2015 Eike Stepper (Berlin, Germany) and others.
 * 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:
 *    Eike Stepper - initial API and implementation
 *
 * $Id: NotUnsettable.java,v 1.2 2011-01-01 11:01:58 estepper Exp $
 */
package org.eclipse.emf.cdo.tests.model2;

import org.eclipse.emf.cdo.tests.model1.VAT;

import org.eclipse.emf.ecore.EObject;

import java.util.Date;

/**
 * <!-- begin-user-doc --> A representation of the model object '<em><b>Not Unsettable</b></em>'. <!-- end-user-doc -->
 *
 * <p>
 * The following features are supported:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.emf.cdo.tests.model2.NotUnsettable#isNotUnsettableBoolean <em>Not Unsettable Boolean</em>}</li>
 *   <li>{@link org.eclipse.emf.cdo.tests.model2.NotUnsettable#getNotUnsettableByte <em>Not Unsettable Byte</em>}</li>
 *   <li>{@link org.eclipse.emf.cdo.tests.model2.NotUnsettable#getNotUnsettableChar <em>Not Unsettable Char</em>}</li>
 *   <li>{@link org.eclipse.emf.cdo.tests.model2.NotUnsettable#getNotUnsettableDate <em>Not Unsettable Date</em>}</li>
 *   <li>{@link org.eclipse.emf.cdo.tests.model2.NotUnsettable#getNotUnsettableDouble <em>Not Unsettable Double</em>}</li>
 *   <li>{@link org.eclipse.emf.cdo.tests.model2.NotUnsettable#getNotUnsettableFloat <em>Not Unsettable Float</em>}</li>
 *   <li>{@link org.eclipse.emf.cdo.tests.model2.NotUnsettable#getNotUnsettableInt <em>Not Unsettable Int</em>}</li>
 *   <li>{@link org.eclipse.emf.cdo.tests.model2.NotUnsettable#getNotUnsettableLong <em>Not Unsettable Long</em>}</li>
 *   <li>{@link org.eclipse.emf.cdo.tests.model2.NotUnsettable#getNotUnsettableShort <em>Not Unsettable Short</em>}</li>
 *   <li>{@link org.eclipse.emf.cdo.tests.model2.NotUnsettable#getNotUnsettableString <em>Not Unsettable String</em>}</li>
 *   <li>{@link org.eclipse.emf.cdo.tests.model2.NotUnsettable#getNotUnsettableVAT <em>Not Unsettable VAT</em>}</li>
 * </ul>
 *
 * @see org.eclipse.emf.cdo.tests.model2.Model2Package#getNotUnsettable()
 * @model
 * @generated
 */
public interface NotUnsettable extends EObject
{
  /**
   * Returns the value of the '<em><b>Not Unsettable Boolean</b></em>' attribute.
   * <!-- begin-user-doc -->
   * <p>
   * If the meaning of the '<em>Not Unsettable Boolean</em>' attribute isn't clear, there really should be more of a
   * description here...
   * </p>
   * <!-- end-user-doc -->
   * @return the value of the '<em>Not Unsettable Boolean</em>' attribute.
   * @see #setNotUnsettableBoolean(boolean)
   * @see org.eclipse.emf.cdo.tests.model2.Model2Package#getNotUnsettable_NotUnsettableBoolean()
   * @model
   * @generated
   */
  boolean isNotUnsettableBoolean();

  /**
   * Sets the value of the '{@link org.eclipse.emf.cdo.tests.model2.NotUnsettable#isNotUnsettableBoolean <em>Not Unsettable Boolean</em>}' attribute.
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   * @param value the new value of the '<em>Not Unsettable Boolean</em>' attribute.
   * @see #isNotUnsettableBoolean()
   * @generated
   */
  void setNotUnsettableBoolean(boolean value);

  /**
   * Returns the value of the '<em><b>Not Unsettable Byte</b></em>' attribute.
   * <!-- begin-user-doc -->
   * <p>
   * If the meaning of the '<em>Not Unsettable Byte</em>' attribute isn't clear, there really should be more of a
   * description here...
   * </p>
   * <!-- end-user-doc -->
   * @return the value of the '<em>Not Unsettable Byte</em>' attribute.
   * @see #setNotUnsettableByte(byte)
   * @see org.eclipse.emf.cdo.tests.model2.Model2Package#getNotUnsettable_NotUnsettableByte()
   * @model
   * @generated
   */
  byte getNotUnsettableByte();

  /**
   * Sets the value of the '{@link org.eclipse.emf.cdo.tests.model2.NotUnsettable#getNotUnsettableByte <em>Not Unsettable Byte</em>}' attribute.
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   * @param value the new value of the '<em>Not Unsettable Byte</em>' attribute.
   * @see #getNotUnsettableByte()
   * @generated
   */
  void setNotUnsettableByte(byte value);

  /**
   * Returns the value of the '<em><b>Not Unsettable Char</b></em>' attribute.
   * <!-- begin-user-doc -->
   * <p>
   * If the meaning of the '<em>Not Unsettable Char</em>' attribute isn't clear, there really should be more of a
   * description here...
   * </p>
   * <!-- end-user-doc -->
   * @return the value of the '<em>Not Unsettable Char</em>' attribute.
   * @see #setNotUnsettableChar(char)
   * @see org.eclipse.emf.cdo.tests.model2.Model2Package#getNotUnsettable_NotUnsettableChar()
   * @model
   * @generated
   */
  char getNotUnsettableChar();

  /**
   * Sets the value of the '{@link org.eclipse.emf.cdo.tests.model2.NotUnsettable#getNotUnsettableChar <em>Not Unsettable Char</em>}' attribute.
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   * @param value the new value of the '<em>Not Unsettable Char</em>' attribute.
   * @see #getNotUnsettableChar()
   * @generated
   */
  void setNotUnsettableChar(char value);

  /**
   * Returns the value of the '<em><b>Not Unsettable Date</b></em>' attribute.
   * <!-- begin-user-doc -->
   * <p>
   * If the meaning of the '<em>Not Unsettable Date</em>' attribute isn't clear, there really should be more of a
   * description here...
   * </p>
   * <!-- end-user-doc -->
   * @return the value of the '<em>Not Unsettable Date</em>' attribute.
   * @see #setNotUnsettableDate(Date)
   * @see org.eclipse.emf.cdo.tests.model2.Model2Package#getNotUnsettable_NotUnsettableDate()
   * @model
   * @generated
   */
  Date getNotUnsettableDate();

  /**
   * Sets the value of the '{@link org.eclipse.emf.cdo.tests.model2.NotUnsettable#getNotUnsettableDate <em>Not Unsettable Date</em>}' attribute.
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   * @param value the new value of the '<em>Not Unsettable Date</em>' attribute.
   * @see #getNotUnsettableDate()
   * @generated
   */
  void setNotUnsettableDate(Date value);

  /**
   * Returns the value of the '<em><b>Not Unsettable Double</b></em>' attribute.
   * <!-- begin-user-doc -->
   * <p>
   * If the meaning of the '<em>Not Unsettable Double</em>' attribute isn't clear, there really should be more of a
   * description here...
   * </p>
   * <!-- end-user-doc -->
   * @return the value of the '<em>Not Unsettable Double</em>' attribute.
   * @see #setNotUnsettableDouble(double)
   * @see org.eclipse.emf.cdo.tests.model2.Model2Package#getNotUnsettable_NotUnsettableDouble()
   * @model
   * @generated
   */
  double getNotUnsettableDouble();

  /**
   * Sets the value of the '{@link org.eclipse.emf.cdo.tests.model2.NotUnsettable#getNotUnsettableDouble <em>Not Unsettable Double</em>}' attribute.
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   * @param value the new value of the '<em>Not Unsettable Double</em>' attribute.
   * @see #getNotUnsettableDouble()
   * @generated
   */
  void setNotUnsettableDouble(double value);

  /**
   * Returns the value of the '<em><b>Not Unsettable Float</b></em>' attribute.
   * <!-- begin-user-doc -->
   * <p>
   * If the meaning of the '<em>Not Unsettable Float</em>' attribute isn't clear, there really should be more of a
   * description here...
   * </p>
   * <!-- end-user-doc -->
   * @return the value of the '<em>Not Unsettable Float</em>' attribute.
   * @see #setNotUnsettableFloat(float)
   * @see org.eclipse.emf.cdo.tests.model2.Model2Package#getNotUnsettable_NotUnsettableFloat()
   * @model
   * @generated
   */
  float getNotUnsettableFloat();

  /**
   * Sets the value of the '{@link org.eclipse.emf.cdo.tests.model2.NotUnsettable#getNotUnsettableFloat <em>Not Unsettable Float</em>}' attribute.
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   * @param value the new value of the '<em>Not Unsettable Float</em>' attribute.
   * @see #getNotUnsettableFloat()
   * @generated
   */
  void setNotUnsettableFloat(float value);

  /**
   * Returns the value of the '<em><b>Not Unsettable Int</b></em>' attribute.
   * <!-- begin-user-doc -->
   * <p>
   * If the meaning of the '<em>Not Unsettable Int</em>' attribute isn't clear, there really should be more of a
   * description here...
   * </p>
   * <!-- end-user-doc -->
   * @return the value of the '<em>Not Unsettable Int</em>' attribute.
   * @see #setNotUnsettableInt(int)
   * @see org.eclipse.emf.cdo.tests.model2.Model2Package#getNotUnsettable_NotUnsettableInt()
   * @model
   * @generated
   */
  int getNotUnsettableInt();

  /**
   * Sets the value of the '{@link org.eclipse.emf.cdo.tests.model2.NotUnsettable#getNotUnsettableInt <em>Not Unsettable Int</em>}' attribute.
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   * @param value the new value of the '<em>Not Unsettable Int</em>' attribute.
   * @see #getNotUnsettableInt()
   * @generated
   */
  void setNotUnsettableInt(int value);

  /**
   * Returns the value of the '<em><b>Not Unsettable Long</b></em>' attribute.
   * <!-- begin-user-doc -->
   * <p>
   * If the meaning of the '<em>Not Unsettable Long</em>' attribute isn't clear, there really should be more of a
   * description here...
   * </p>
   * <!-- end-user-doc -->
   * @return the value of the '<em>Not Unsettable Long</em>' attribute.
   * @see #setNotUnsettableLong(long)
   * @see org.eclipse.emf.cdo.tests.model2.Model2Package#getNotUnsettable_NotUnsettableLong()
   * @model
   * @generated
   */
  long getNotUnsettableLong();

  /**
   * Sets the value of the '{@link org.eclipse.emf.cdo.tests.model2.NotUnsettable#getNotUnsettableLong <em>Not Unsettable Long</em>}' attribute.
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   * @param value the new value of the '<em>Not Unsettable Long</em>' attribute.
   * @see #getNotUnsettableLong()
   * @generated
   */
  void setNotUnsettableLong(long value);

  /**
   * Returns the value of the '<em><b>Not Unsettable Short</b></em>' attribute.
   * <!-- begin-user-doc -->
   * <p>
   * If the meaning of the '<em>Not Unsettable Short</em>' attribute isn't clear, there really should be more of a
   * description here...
   * </p>
   * <!-- end-user-doc -->
   * @return the value of the '<em>Not Unsettable Short</em>' attribute.
   * @see #setNotUnsettableShort(short)
   * @see org.eclipse.emf.cdo.tests.model2.Model2Package#getNotUnsettable_NotUnsettableShort()
   * @model
   * @generated
   */
  short getNotUnsettableShort();

  /**
   * Sets the value of the '{@link org.eclipse.emf.cdo.tests.model2.NotUnsettable#getNotUnsettableShort <em>Not Unsettable Short</em>}' attribute.
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   * @param value the new value of the '<em>Not Unsettable Short</em>' attribute.
   * @see #getNotUnsettableShort()
   * @generated
   */
  void setNotUnsettableShort(short value);

  /**
   * Returns the value of the '<em><b>Not Unsettable String</b></em>' attribute.
   * <!-- begin-user-doc -->
   * <p>
   * If the meaning of the '<em>Not Unsettable String</em>' attribute isn't clear, there really should be more of a
   * description here...
   * </p>
   * <!-- end-user-doc -->
   * @return the value of the '<em>Not Unsettable String</em>' attribute.
   * @see #setNotUnsettableString(String)
   * @see org.eclipse.emf.cdo.tests.model2.Model2Package#getNotUnsettable_NotUnsettableString()
   * @model
   * @generated
   */
  String getNotUnsettableString();

  /**
   * Sets the value of the '{@link org.eclipse.emf.cdo.tests.model2.NotUnsettable#getNotUnsettableString <em>Not Unsettable String</em>}' attribute.
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   * @param value the new value of the '<em>Not Unsettable String</em>' attribute.
   * @see #getNotUnsettableString()
   * @generated
   */
  void setNotUnsettableString(String value);

  /**
   * Returns the value of the '<em><b>Not Unsettable VAT</b></em>' attribute.
   * The literals are from the enumeration {@link org.eclipse.emf.cdo.tests.model1.VAT}.
   * <!-- begin-user-doc -->
   * <p>
   * If the meaning of the '<em>Not Unsettable VAT</em>' attribute isn't clear, there really should be more of a
   * description here...
   * </p>
   * <!-- end-user-doc -->
   * @return the value of the '<em>Not Unsettable VAT</em>' attribute.
   * @see org.eclipse.emf.cdo.tests.model1.VAT
   * @see #setNotUnsettableVAT(VAT)
   * @see org.eclipse.emf.cdo.tests.model2.Model2Package#getNotUnsettable_NotUnsettableVAT()
   * @model
   * @generated
   */
  VAT getNotUnsettableVAT();

  /**
   * Sets the value of the '{@link org.eclipse.emf.cdo.tests.model2.NotUnsettable#getNotUnsettableVAT <em>Not Unsettable VAT</em>}' attribute.
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   * @param value the new value of the '<em>Not Unsettable VAT</em>' attribute.
   * @see org.eclipse.emf.cdo.tests.model1.VAT
   * @see #getNotUnsettableVAT()
   * @generated
   */
  void setNotUnsettableVAT(VAT value);

} // NotUnsettable
