gt:                 for (int i = 0; i < o.length; i++) {
context: /**
   * Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
   * Licensed under the terms of the Eclipse Public License (EPL).
   * Please see the license.txt included with this distribution for details.
   * Any modifications to this file must keep this entire header intact.
   */
  /*
   * Created on 23/07/2005
   */
  package com.python.pydev.analysis.messages;
  
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  
  import org.eclipse.core.runtime.Assert;
  import org.eclipse.jface.text.BadLocationException;
  import org.eclipse.jface.text.IDocument;
  import org.eclipse.jface.text.IRegion;
  import org.python.pydev.core.FullRepIterable;
  import org.python.pydev.core.IToken;
  import org.python.pydev.core.docutils.StringUtils;
  import org.python.pydev.editor.codecompletion.revisited.modules.SourceToken;
  import org.python.pydev.editor.codecompletion.revisited.visitors.AbstractVisitor;
  import org.python.pydev.parser.jython.SimpleNode;
  import org.python.pydev.parser.jython.ast.Import;
  import org.python.pydev.parser.jython.ast.ImportFrom;
  import org.python.pydev.parser.jython.ast.NameTok;
  import org.python.pydev.parser.jython.ast.aliasType;
  
  import com.aptana.shared_core.string.FastStringBuffer;
  import com.python.pydev.analysis.IAnalysisPreferences;
  
  public abstract class AbstractMessage implements IMessage {
  
      public static final Map<Integer, String> messages = new HashMap<Integer, String>();
  
      private final int type;
  
      private final int severity;
  
      private IToken generator;
  
      private List<String> additionalInfo;
  
      private int startLine = -1;
  
      /**
       * @param generator needed to get the lines/cols for the message (an alternate constructor is given if 
       * it's already known).
       */
      public AbstractMessage(int type, IToken generator, IAnalysisPreferences prefs) {
          this.severity = prefs.getSeverityForType(type);
          this.type = type;
          this.generator = generator;
          try {
              Assert.isNotNull(generator);
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  
      /**
       * @param startLine starts at 1
       * @param endLine starts at 1
       * @param startCol starts at 1
       * @param endCol starts at 1
       */
      public AbstractMessage(int type, int startLine, int endLine, int startCol, int endCol, IAnalysisPreferences prefs) {
          this.severity = prefs.getSeverityForType(type);
          this.type = type;
          Assert.isTrue(startLine >= 0);
          Assert.isTrue(startCol >= 0);
          this.startLine = startLine;
          this.startCol = startCol;
          this.endLine = endLine;
          this.endCol = endCol;
      }
  
      private String getTypeStr() {
          if (messages.size() == 0) {
              messages.put(IAnalysisPreferences.TYPE_UNUSED_IMPORT, "Unused import: %s");
              messages.put(IAnalysisPreferences.TYPE_UNUSED_WILD_IMPORT, "Unused in wild import: %s");
              messages.put(IAnalysisPreferences.TYPE_UNUSED_VARIABLE, "Unused variable: %s");
              messages.put(IAnalysisPreferences.TYPE_UNUSED_PARAMETER, "Unused parameter: %s");
              messages.put(IAnalysisPreferences.TYPE_UNDEFINED_VARIABLE, "Undefined variable: %s");
              messages.put(IAnalysisPreferences.TYPE_DUPLICATED_SIGNATURE, "Duplicated signature: %s");
              messages.put(IAnalysisPreferences.TYPE_REIMPORT, "Import redefinition: %s");
              messages.put(IAnalysisPreferences.TYPE_UNRESOLVED_IMPORT, "Unresolved import: %s");
              messages.put(IAnalysisPreferences.TYPE_NO_SELF, "Method '%s' should have %s as first parameter");
              messages.put(IAnalysisPreferences.TYPE_UNDEFINED_IMPORT_VARIABLE, "Undefined variable from import: %s");
              messages.put(IAnalysisPreferences.TYPE_NO_EFFECT_STMT, "Statement apppears to have no effect");
              messages.put(IAnalysisPreferences.TYPE_INDENTATION_PROBLEM, "%s");
              messages.put(IAnalysisPreferences.TYPE_ASSIGNMENT_TO_BUILT_IN_SYMBOL,
                      "Assignment to reserved built-in symbol: %s");
              messages.put(IAnalysisPreferences.TYPE_PEP8, "%s");
              messages.put(IAnalysisPreferences.TYPE_ARGUMENTS_MISATCH, "%s");
          }
          return messages.get(getType());
  
      }
  
      public int getSeverity() {
          return severity;
      }
  
      public int getType() {
          return type;
      }
  
      public int getStartLine(IDocument doc) {
          if (startLine < 0) {
              startLine = getStartLine(generator, doc);
          }
          return startLine;
      }
  
      /**
       * @return the starting line fro the given token (starting at 1)
       */
      public static int getStartLine(IToken generator, IDocument doc) {
          return getStartLine(generator, doc, generator.getRepresentation());
      }
  
      public static int getStartLine(IToken generator, IDocument doc, String shortMessage) {
          return getStartLine(generator, doc, shortMessage, false);
  
      }
  
      public static int getStartLine(IToken generator, IDocument doc, String shortMessage, boolean returnAsName) {
          if (!generator.isImport()) {
              return generator.getLineDefinition();
          }
  
          //ok, it is an import... (can only be a source token)
          SourceToken s = (SourceToken) generator;
  
          SimpleNode ast = s.getAst();
          if (ast instanceof ImportFrom) {
              ImportFrom i = (ImportFrom) ast;
              //if it is a wild import, it starts on the module name
              if (AbstractVisitor.isWildImport(i)) {
                  return i.module.beginLine;
              } else {
                  //no wild import, let's check the 'as name'
                  return getNameForRepresentation(i, shortMessage, returnAsName).beginLine;
              }
  
          } else if (ast instanceof Import) {
              return getNameForRepresentation(ast, shortMessage, returnAsName).beginLine;
  
          } else {
              throw new RuntimeException("It is not an import");
          }
      }
  
      int startCol = -1;
  
      /**
       * gets the start col of the message (starting at 1)
       *  
       * @see com.python.pydev.analysis.messages.IMessage#getStartCol(org.eclipse.jface.text.IDocument)
       */
      public int getStartCol(IDocument doc) {
          if (startCol >= 0) {
              return startCol;
          }
          startCol = getStartCol(generator, doc, getShortMessageStr());
          return startCol;
  
      }
  
      private String getShortMessageStr() {
          Object msg = getShortMessage();
          if (msg instanceof Object[]) {
              Object[] msgs = (Object[]) msg;
              FastStringBuffer buffer = new FastStringBuffer();
              for (Object o : msgs) {
                  buffer.append(o.toString());
              }
              return buffer.toString();
          } else {
              return msg.toString();
          }
      }
  
      /**
       * @return the starting column for the given token (1-based)
       */
      public static int getStartCol(IToken generator, IDocument doc) {
          return getStartCol(generator, doc, generator.getRepresentation());
      }
  
      /**
       * @return the starting column for the given token (1-based)
       */
      public static int getStartCol(IToken generator, IDocument doc, String shortMessage) {
          return getStartCol(generator, doc, shortMessage, false);
  
      }
  
      /**
       * @return the starting column for the given token (1-based)
       */
      public static int getStartCol(IToken generator, IDocument doc, String shortMessage, boolean returnAsName) {
  
          //not import...
          if (!generator.isImport()) {
              return generator.getColDefinition();
          }
  
          //ok, it is an import... (can only be a source token)
          SourceToken s = (SourceToken) generator;
  
          SimpleNode ast = s.getAst();
          if (ast instanceof ImportFrom) {
              ImportFrom i = (ImportFrom) ast;
              //if it is a wild import, it starts on the module name
              if (AbstractVisitor.isWildImport(i)) {
                  return i.module.beginColumn;
              } else {
                  //no wild import, let's check the 'as name'
                  return getNameForRepresentation(i, shortMessage, returnAsName).beginColumn;
              }
  
          } else if (ast instanceof Import) {
              return getNameForRepresentation(ast, shortMessage, returnAsName).beginColumn;
  
          } else {
              throw new RuntimeException("It is not an import");
          }
      }
  
      /**
       * @param imp this is the import ast
       * @param fullRep this is the representation we are looking for
       * @param returnAsName defines if we should return the asname or only the name (depending on what we are
       * analyzing -- the start or the end of the representation).
       * 
       * @return the name tok for the representation in a given import
       */
      private static NameTok getNameForRepresentation(SimpleNode imp, String rep, boolean returnAsName) {
  
          aliasType[] names;
          if (imp instanceof Import) {
              names = ((Import) imp).names;
          } else if (imp instanceof ImportFrom) {
              names = ((ImportFrom) imp).names;
          } else {
              throw new RuntimeException("import expected");
          }
  
          for (aliasType alias : names) {
              if (alias.asname != null) {
                  if (((NameTok) alias.asname).id.equals(rep)) {
                      if (returnAsName) {
                          return (NameTok) alias.asname;
                      } else {
                          return (NameTok) alias.name;
                      }
                  }
              } else { //let's check for the name
  
                  String fullRepNameId = ((NameTok) alias.name).id;
  
                  //we have to get all representations, since an import such as import os.path would 
                  //have to match os and os.path
                  for (String repId : new FullRepIterable(fullRepNameId)) {
  
                      if (repId.equals(rep)) {
                          return (NameTok) alias.name;
                      }
                  }
              }
          }
          return null;
      }
  
      /**
       * @see com.python.pydev.analysis.messages.IMessage#getEndLine(org.eclipse.jface.text.IDocument)
       */
      int endLine = -1;
  
      public int getEndLine(IDocument doc) {
          return getEndLine(doc, true);
      }
  
      public int getEndLine(IDocument doc, boolean getOnlyToFirstDot) {
          if (endLine < 0) {
              endLine = getEndLine(generator, doc, getOnlyToFirstDot);
          }
          return endLine;
  
      }
  
      public static int getEndLine(IToken generator, IDocument doc, boolean getOnlyToFirstDot) {
          if (generator instanceof SourceToken) {
              if (!generator.isImport()) {
                  return ((SourceToken) generator).getLineEnd(getOnlyToFirstDot);
              }
              return getStartLine(generator, doc); //for an import, the endline == startline
  
          } else {
              return -1;
          }
      }
  
      int endCol = -1;
  
      public int getEndCol(IDocument doc) {
          return getEndCol(doc, true);
      }
  
      public int getEndCol(IDocument doc, boolean getOnlyToFirstDot) {
          if (endCol >= 0) {
              return endCol;
          }
          endCol = getEndCol(generator, doc, getShortMessageStr(), getOnlyToFirstDot);
          return endCol;
  
      }
  
      /**
       * @param generator is the token that generated this message
       * @param doc is the document where this message will be put
       * @param shortMessage is used when it is an import ( = foundTok.getRepresentation())
       * 
       * @return the end column for this message
       *  
       * @see com.python.pydev.analysis.messages.IMessage#getEndCol(org.eclipse.jface.text.IDocument)
       */
      public static int getEndCol(IToken generator, IDocument doc, String shortMessage, boolean getOnlyToFirstDot) {
          int endCol = -1;
          if (generator.isImport()) {
              //ok, it is an import... (can only be a source token)
              SourceToken s = (SourceToken) generator;
  
              SimpleNode ast = s.getAst();
  
              if (ast instanceof ImportFrom) {
                  ImportFrom i = (ImportFrom) ast;
                  //ok, now, this depends on the name
                  NameTok it = getNameForRepresentation(i, shortMessage, true);
                  if (it != null) {
                      endCol = it.beginColumn + shortMessage.length();
                      return endCol;
                  }
  
                  //if still not returned, it is a wild import... find the '*'
                  try {
                      IRegion lineInformation = doc.getLineInformation(i.module.beginLine - 1);
                      //ok, we have the line... now, let's find the absolute offset
                      int absolute = lineInformation.getOffset() + i.module.beginColumn - 1;
                      while (doc.getChar(absolute) != '*') {
                          absolute++;
                      }
                      int absoluteCol = absolute + 1; //1 for the *
                      IRegion region = doc.getLineInformationOfOffset(absoluteCol);
                      endCol = absoluteCol - region.getOffset() + 1; //1 because we should return as if starting in 1 and not 0
                      return endCol;
                  } catch (BadLocationException e) {
                      throw new RuntimeException(e);
                  }
  
              } else if (ast instanceof Import) {
                  NameTok it = getNameForRepresentation((Import) ast, shortMessage, true);
                  endCol = it.beginColumn + shortMessage.length();
                  return endCol;
              } else {
                  throw new RuntimeException("It is not an import");
              }
          }
  
          //no import... make it regular
          if (generator instanceof SourceToken) {
              return ((SourceToken) generator).getColEnd(getOnlyToFirstDot);
          }
          return -1;
      }
  
      public String toString() {
          return getMessage();
      }
  
      public List<String> getAdditionalInfo() {
          return additionalInfo;
      }
  
      public void addAdditionalInfo(String info) {
          if (this.additionalInfo == null) {
              this.additionalInfo = new ArrayList<String>();
          }
          this.additionalInfo.add(info);
      }
  
      String message = null;
  
      public String getMessage() {
          if (message != null) {
              return message;
          }
  
          String typeStr = getTypeStr();
          if (typeStr == null) {
              throw new AssertionError("Unable to get message for type: " + getType());
          }
          Object shortMessage = getShortMessage();
          if (shortMessage == null) {
              throw new AssertionError("Unable to get shortMessage (" + typeStr + ")");
          }
          if (shortMessage instanceof Object[]) {
              Object[] o = (Object[]) shortMessage;
  
              //if we have the same number of %s as objects in the array, make the format
              int countPercS = StringUtils.countPercS(typeStr);
              if (countPercS == o.length) {
                  return com.aptana.shared_core.string.StringUtils.format(typeStr, o);
  
              } else if (countPercS == 1) {
                  //if we have only 1, all parameters should be concatenated in a single string
                  FastStringBuffer buf = new FastStringBuffer();
  