private List<Statement> getStatements(Tree.Body body, ITextSelection selection) {
   List<Statement> statements = new ArrayList<Statement>();
   for (Tree.Statement s : body.getStatements()) {
     if (s.getStartIndex() >= selection.getOffset()
         && s.getStopIndex() <= selection.getOffset() + selection.getLength()) {
       statements.add(s);
     }
   }
   return statements;
 }
 static void addCreateParameterAndAttributeProposal(
     Collection<ICompletionProposal> proposals,
     String pdef,
     String adef,
     String desc,
     Image image,
     Declaration dec,
     PhasedUnit unit,
     Tree.Declaration decNode,
     Tree.ParameterList paramList,
     Tree.Body body,
     ProducedType t) {
   IFile file = CeylonBuilder.getFile(unit);
   TextFileChange change = new TextFileChange("Add Attribute", file);
   change.setEdit(new MultiTextEdit());
   int offset = paramList.getStopIndex();
   IDocument doc = CreateProposal.getDocument(change);
   String indent;
   String indentAfter;
   int offset2;
   List<Tree.Statement> statements = body.getStatements();
   if (statements.isEmpty()) {
     indentAfter = "\n" + CeylonQuickFixAssistant.getIndent(decNode, doc);
     indent = indentAfter + getDefaultIndent();
     offset2 = body.getStartIndex() + 1;
   } else {
     Tree.Statement statement = statements.get(statements.size() - 1);
     indent = "\n" + CeylonQuickFixAssistant.getIndent(statement, doc);
     offset2 = statement.getStopIndex() + 1;
     indentAfter = "";
   }
   int il = importType(change, t, unit.getCompilationUnit());
   change.addEdit(new InsertEdit(offset, pdef));
   change.addEdit(new InsertEdit(offset2, indent + adef + indentAfter));
   proposals.add(
       new CreateProposal(
           pdef,
           "Add " + desc + " to '" + dec.getName() + "'",
           image,
           0,
           offset + il,
           file,
           change));
 }
 static void addCreateEnumProposal(
     Collection<ICompletionProposal> proposals,
     String def,
     String desc,
     Image image,
     PhasedUnit unit,
     Tree.Statement statement) {
   IFile file = CeylonBuilder.getFile(unit);
   TextFileChange change = new TextFileChange("Create Enumerated", file);
   IDocument doc = CreateProposal.getDocument(change);
   String indent = CeylonQuickFixAssistant.getIndent(statement, doc);
   String s = indent + def + "\n";
   int offset = statement.getStopIndex() + 2;
   if (offset > doc.getLength()) {
     offset = doc.getLength();
     s = "\n" + s;
   }
   // def = def.replace("$indent", indent);
   change.setEdit(new InsertEdit(offset, s));
   proposals.add(
       new CreateProposal(def, "Create enumerated " + desc, image, 0, offset, file, change));
 }
 static void addCreateMemberProposal(
     Collection<ICompletionProposal> proposals,
     DefinitionGenerator dg,
     Declaration typeDec,
     PhasedUnit unit,
     Tree.Declaration decNode,
     Tree.Body body,
     Tree.Statement statement) {
   IFile file = getFile(unit);
   TextFileChange change = new TextFileChange("Create Member", file);
   change.setEdit(new MultiTextEdit());
   IDocument doc = EditorUtil.getDocument(change);
   String indentBefore;
   String indentAfter;
   String indent;
   int offset;
   List<Tree.Statement> statements = body.getStatements();
   String delim = getDefaultLineDelimiter(doc);
   if (statements.isEmpty()) {
     String bodyIndent = getIndent(decNode, doc);
     indent = bodyIndent + getDefaultIndent();
     indentBefore = delim + indent;
     try {
       boolean singleLineBody =
           doc.getLineOfOffset(body.getStartIndex()) == doc.getLineOfOffset(body.getStopIndex());
       if (singleLineBody) {
         indentAfter = delim + bodyIndent;
       } else {
         indentAfter = "";
       }
     } catch (BadLocationException e) {
       e.printStackTrace();
       indentAfter = delim;
     }
     offset = body.getStartIndex() + 1;
   } else {
     Tree.Statement st;
     if (statement != null
         && statement.getUnit().equals(body.getUnit())
         && statement.getStartIndex() >= body.getStartIndex()
         && statement.getStopIndex() <= body.getStopIndex()) {
       st = statements.get(0);
       for (Tree.Statement s : statements) {
         if (statement.getStartIndex() >= s.getStartIndex()
             && statement.getStopIndex() <= s.getStopIndex()) {
           st = s;
         }
       }
       indent = getIndent(st, doc);
       indentBefore = "";
       indentAfter = delim + indent;
       offset = st.getStartIndex();
     } else {
       st = statements.get(statements.size() - 1);
       indent = getIndent(st, doc);
       indentBefore = delim + indent;
       indentAfter = "";
       offset = st.getStopIndex() + 1;
     }
   }
   String generated =
       typeDec instanceof Interface
           ? dg.generateSharedFormal(indent, delim)
           : dg.generateShared(indent, delim);
   String def = indentBefore + generated + indentAfter;
   int il = applyImports(change, dg.getImports(), unit.getCompilationUnit(), doc);
   change.addEdit(new InsertEdit(offset, def));
   String desc = "Create " + memberKind(dg) + " in '" + typeDec.getName() + "'";
   int exitPos = dg.getNode().getStopIndex() + 1;
   proposals.add(
       new CreateProposal(
           def,
           desc,
           body.getScope(),
           body.getUnit(),
           dg.getReturnType(),
           dg.getImage(),
           offset + il,
           change,
           exitPos,
           dg instanceof ObjectClassDefinitionGenerator));
 }