public static void main(String[] args) {

    Lexer lexer = new Lexer();
    Tokenizer tokenizer = new Tokenizer(lexer);
    VariableParser fparser = new VariableParser(tokenizer, null, null);

    try {
      lexer.scan(new File("test/test_go/import_test.go"));
      for (Var var : fparser.vars) {
        Activator.logInfo("=================================================");
        Activator.logInfo(var.getDocumentation());
        Activator.logInfo("-------------------------------------------------");
        Activator.logInfo(var.getName());
        Activator.logInfo(var.getInsertionText());
        Activator.logInfo("-------------------------------------------------");
      }

    } catch (IOException e) {
      Activator.logError(e);
    }
  }
  @Override
  public void tokenFound(
      TokenType type, String value, boolean inComment, int linenumber, int start, int end) {

    if (inComment) {
      if (!TokenType.COMMENT.equals(type)
          && !TokenType.BLOCK_COMMENT_START.equals(type)
          && !TokenType.BLOCK_COMMENT_END.equals(type)) {

        if (linenumber > lastCommentLine && TokenType.DIVIDE.equals(type)) {
          lastCommentLine = linenumber;
        } else {
          comment.append(value);
          lastCommentLine = linenumber;
        }
      }
      return;
    }

    handleVarBufferFlush(type);

    if (linenumber - lastCommentLine > 1) {
      comment = new StringBuffer();
    }

    // System.out.println(state);

    if (!inComment) {

      switch (state) {
        case START:
          if (TokenType.VAR.equals(type)) {
            state = State.SIMPLE_VAR;

          } else if ((TokenType.INFERENCE.equals(type))) {
            // TODO this inference parsing does not work
            // System.out.println("State Changed On: "+ type +":"+ value);
            state = State.INFERENCE;
          }
          break;

          // var name type
        case SIMPLE_VAR:
          if (TokenType.IDENTIFIER.equals(type)) {
            var.setName(value);
            var.setInsertionText(value);
            var.setDocumentation(comment.toString());
            var.setLine(linenumber);
            state = State.SIMPLE_TYPE;
          }
          break;

        case SIMPLE_TYPE:
          boolean found = false;

          // this isn't very clean, I'll have to come back a rethink all this
          // is TypeClass enough???
          if (TokenType.IDENTIFIER.equals(type)) {
            var.setTypeClass(TypeClass.USER);
            var.setName(var.getName() + " : " + value);
            found = true;
          } else if (TokenType.UINT.equals(type)) {
            var.setTypeClass(TypeClass.UINT);
            var.setName(var.getName() + " : " + type.getText());
            found = true;
          } else if (TokenType.UINT8.equals(type)) {
            var.setTypeClass(TypeClass.UINT8);
            var.setName(var.getName() + " : " + type.getText());
            found = true;
          } else if (TokenType.UINT16.equals(type)) {
            var.setTypeClass(TypeClass.UINT16);
            var.setName(var.getName() + " : " + type.getText());
            found = true;
          } else if (TokenType.UINT32.equals(type)) {
            var.setTypeClass(TypeClass.UINT32);
            var.setName(var.getName() + " : " + type.getText());
            found = true;
          } else if (TokenType.UINT64.equals(type)) {
            var.setTypeClass(TypeClass.UINT64);
            var.setName(var.getName() + " : " + type.getText());
            found = true;
          } else if (TokenType.RUNE.equals(type)) {
            var.setTypeClass(TypeClass.RUNE);
            var.setName(var.getName() + " : " + type.getText());
            found = true;
          } else if (TokenType.INT.equals(type)) {
            var.setTypeClass(TypeClass.INT);
            var.setName(var.getName() + " : " + type.getText());
            found = true;
          } else if (TokenType.INT8.equals(type)) {
            var.setTypeClass(TypeClass.INT8);
            var.setName(var.getName() + " : " + type.getText());
            found = true;
          } else if (TokenType.INT16.equals(type)) {
            var.setTypeClass(TypeClass.INT16);
            var.setName(var.getName() + " : " + type.getText());
            found = true;
          } else if (TokenType.INT32.equals(type)) {
            var.setTypeClass(TypeClass.INT32);
            var.setName(var.getName() + " : " + type.getText());
            found = true;
          } else if (TokenType.INT64.equals(type)) {
            var.setTypeClass(TypeClass.INT64);
            var.setName(var.getName() + " : " + type.getText());
            found = true;
          } else if (TokenType.FLOAT32.equals(type)) {
            var.setTypeClass(TypeClass.FLOAT32);
            var.setName(var.getName() + " : " + type.getText());
            found = true;
          } else if (TokenType.FLOAT64.equals(type)) {
            var.setTypeClass(TypeClass.FLOAT64);
            var.setName(var.getName() + " : " + type.getText());
            found = true;
          } else if (TokenType.BYTE.equals(type)) {
            var.setTypeClass(TypeClass.BYTE);
            var.setName(var.getName() + " : " + type.getText());
            found = true;
          } else if (TokenType.UINTPTR.equals(type)) {
            var.setTypeClass(TypeClass.UINTPTR);
            var.setName(var.getName() + " : " + type.getText());
            found = true;
          } else if (TokenType.STRING.equals(type)) {
            var.setTypeClass(TypeClass.STRING);
            var.setName(var.getName() + " : " + type.getText());
            found = true;
          } else if (TokenType.BOOL.equals(type)) {
            var.setTypeClass(TypeClass.BOOL);
            var.setName(var.getName() + " : " + type.getText());
            found = true;
          } else if (TokenType.CHAN.equals(type)) {
            var.setTypeClass(TypeClass.CHAN);
            var.setChan(true);
            found = true;
          } else if (TokenType.MAP.equals(type)) {
            var.setTypeClass(TypeClass.MAP);
            var.setMap(true);
            found = true;
          } else if (TokenType.LBRACKET.equals(type)) {
            var.setTypeClass(TypeClass.ARRAY);
            var.setArray(true);
            found = false;
          } else if (TokenType.MULTIPLY.equals(type)) {
            var.setPointer(true);
            found = false;
          }

          if (found) {

            state = State.START;
            vars.add(var);
            var.setLine(linenumber);

            if (scopeParser != null) {
              scopeParser.addVariable(var);
            }

            var = new Var();
            var.setFile(file);
            comment = new StringBuffer();
          }

          break;

        case INFERENCE:
          for (String s : previousIdentifier) {

            if (var.getInsertionText() == null) {
              var.setInsertionText(s);
            }

            state = State.START;
            vars.add(var);
            var.setLine(linenumber);

            if (scopeParser != null) {
              scopeParser.addVariable(var);
            }

            var = new Var();
            var.setFile(file);
            comment = new StringBuffer();
          }

          previousIdentifier.clear();
          break;
      }
    }

    // keep track of the last identifier for inferenced variables
    if (TokenType.IDENTIFIER.equals(type)) {
      previousIdentifier.add(value);

    } else if (!TokenType.COMMA.equals(type)
        && !TokenType.SPACE.equals(type)
        && !TokenType.NEWLINE.equals(type)
        && !TokenType.TAB.equals(type)
        && !TokenType.TYPE.equals(type)) {

      previousIdentifier.clear();
    }
  }
 /** @param tokenizer */
 public VariableParser(Tokenizer tokenizer, File file, FunctionParser functionParser) {
   tokenizer.addTokenListener(this);
   this.file = file;
   var.setFile(file);
   this.functionParser = functionParser;
 }