@Override
  public Object visit(
      VariableDeclarationExpression variableDeclarationExpression,
      TypeResolutionContext context,
      EolVisitorController<TypeResolutionContext, Object> controller) {

    // visit contents first
    controller.visitContents(variableDeclarationExpression, context);

    // if create is not null
    if (variableDeclarationExpression.getCreate() != null) {

      // get the value of the create
      boolean newExpression = variableDeclarationExpression.getCreate().isVal();

      // if it is a new variable
      if (newExpression) {

        // get resolved type
        Type rawType = variableDeclarationExpression.getResolvedType();

        // we are interested in the model element types
        if (rawType instanceof ModelElementType) {

          // get the type
          ModelElementType modelElementType = (ModelElementType) rawType;

          // if the model element type is a EClass in the meta model
          if (modelElementType.getEcoreType() instanceof EClass) {

            // get the EClass
            EClass eClass = (EClass) modelElementType.getEcoreType();

            // check if the class is an interface or abstract
            if (eClass.isAbstract() || eClass.isInterface()) {

              context
                  .getLogBook()
                  .addError(
                      modelElementType, "Model element type is not instantiable"); // throw error
            }
          }
        }
      }
    }
    return null;
  }
  @Override
  public EolElement create(AST ast, EolElement container, Ast2EolContext context) {

    OperationDefinition operation =
        (OperationDefinition)
            context.getEolFactory().createOperationDefinition(); // create an OperationDefinition

    this.setAssets(ast, operation, container);

    AST previousAst = AstUtilities.getPreviousSibling(ast); // get the previous sibling
    if (previousAst.getType() == EolParser.ANNOTATIONBLOCK) // check if there is an annotation block
    {
      operation.setAnnotationBlock(
          (AnnotationBlock)
              context
                  .getEolElementCreatorFactory()
                  .createDomElement(previousAst, operation, context)); // process annotation block
    }

    AST contextTypeAst = null; // declare contextTypeAst
    AST nameAst = null; // declare nameAst
    AST parameterListAst = null; // declare parameterListAst
    AST returnTypeAst = null; // declare returnTypeAst
    AST bodyAst = null; // declare bodyAst

    if (ast.getFirstChild().getType() == EolParser.TYPE) { // if there is a contextType specified
      contextTypeAst = ast.getFirstChild(); // assign contextTypeAst
      nameAst = contextTypeAst.getNextSibling(); // assign nameAst
    } else { // if there is no contextType specified
      nameAst = ast.getFirstChild(); // assign nameAst

      // Type contextType = context.getEolFactory().createAnyType(); //if there's no context type,
      // it should be any
      // setAssets(nameAst, contextType, operation);
      // operation.setContextType(contextType);

    }

    if (nameAst.getNextSibling().getType() == EolParser.PARAMLIST) { // if there is a parameter list
      parameterListAst = nameAst.getNextSibling(); // assign parameterListAst
    }

    if (parameterListAst != null) { // helper with parameters
      if (parameterListAst.getNextSibling().getType()
          == EolParser.TYPE) { // it there is a return type specified
        returnTypeAst = parameterListAst.getNextSibling();
        bodyAst = returnTypeAst.getNextSibling();
      } else { // if there is no return type
        bodyAst = parameterListAst.getNextSibling();
      }
    } else { // helper without parameters
      if (nameAst.getNextSibling().getType()
          == EolParser.TYPE) { // if there is a return type specified
        returnTypeAst = nameAst.getNextSibling(); // assign return type
        bodyAst = returnTypeAst.getNextSibling(); // assign bodyAst
      } else { // without return type
        bodyAst = nameAst.getNextSibling(); // assign bodyAst
      }
    }

    if (contextTypeAst != null) // if there is a contextType
    {
      Type contextType =
          (Type)
              context
                  .getEolElementCreatorFactory()
                  .createDomElement(contextTypeAst, operation, context); // process context type
      operation.setContextType(contextType); // assign context type
    }

    operation.setName(
        (NameExpression)
            context
                .getEolElementCreatorFactory()
                .createDomElement(nameAst, operation, context)); // process name

    if (parameterListAst != null) // if there is a parameter list
    {
      for (AST parameterAst : parameterListAst.getChildren()) {
        operation
            .getParameters()
            .add(
                (FormalParameterExpression)
                    context
                        .getEolElementCreatorFactory()
                        .createDomElement(parameterAst, operation, context));
      }
    }

    if (returnTypeAst != null) // if there is a return type
    {
      Type returnType =
          (Type)
              context
                  .getEolElementCreatorFactory()
                  .createDomElement(returnTypeAst, operation, context); // create a return type
      operation.setReturnType(returnType); // assign the return type to the operation
    } else {
      Type returnType =
          context.getEolFactory().createVoidType(); // if there's no return type, it should be void
      setAssets(nameAst, returnType, operation);
      operation.setReturnType(returnType);
    }

    if (bodyAst != null) // if there is a body
    {
      operation.setBody(
          (Block)
              context
                  .getEolElementCreatorFactory()
                  .createDomElement(bodyAst, operation, context)); // process body
    }

    if (contextTypeAst != null) {
      VariableDeclarationExpression self =
          context.getEolFactory().createVariableDeclarationExpression();
      NameExpression selfName = context.getEolFactory().createNameExpression();
      selfName.setName("self");
      self.setName(selfName);
      self.setResolvedType(EcoreUtil.copy(operation.getContextType()));

      operation.setSelf(self);
    } else {
      operation.setSelf(null);
    }

    if (returnTypeAst
        != null) { // this is based on the assumption that a operation definition MUST define a
      // returnType if it returns anything
      VariableDeclarationExpression _result =
          context.getEolFactory().createVariableDeclarationExpression();
      NameExpression resultName = context.getEolFactory().createNameExpression();
      resultName.setName("_result");
      _result.setName(resultName);
      _result.setResolvedType(EcoreUtil.copy(operation.getContextType()));

      operation.set_result(_result);
    }

    return operation;
  }