private static boolean spreadable(Parameter param, List<Parameter> list) {
   Parameter lastParam = list.get(list.size() - 1);
   if (param == lastParam && param.getModel() instanceof Value) {
     Type type = param.getType();
     Unit unit = param.getDeclaration().getUnit();
     return type != null && unit.isIterableParameterType(type);
   } else {
     return false;
   }
 }
  private Referenceable resolveNative(
      Referenceable referenceable, Declaration dec, Backends backends) {
    Unit unit = dec.getUnit();
    Scope containerToSearchHeaderIn = null;
    if (unit instanceof CeylonBinaryUnit) {
      CeylonBinaryUnit binaryUnit = (CeylonBinaryUnit) unit;
      ExternalPhasedUnit phasedUnit = binaryUnit.getPhasedUnit();
      if (phasedUnit != null) {
        ExternalSourceFile sourceFile = phasedUnit.getUnit();
        if (sourceFile != null) {
          String sourceRelativePath =
              toJavaString(
                  binaryUnit
                      .getCeylonModule()
                      .toSourceUnitRelativePath(toCeylonString(unit.getRelativePath())));
          if (sourceRelativePath != null && sourceRelativePath.endsWith(".ceylon")) {
            for (Declaration sourceDecl : sourceFile.getDeclarations()) {
              if (sourceDecl.equals(dec)) {
                containerToSearchHeaderIn = sourceDecl.getContainer();
                break;
              }
            }
          } else {
            for (Declaration sourceDecl : sourceFile.getDeclarations()) {
              if (sourceDecl.getQualifiedNameString().equals(dec.getQualifiedNameString())) {
                containerToSearchHeaderIn = sourceDecl.getContainer();
                break;
              }
            }
          }
        }
      }
    } else {
      containerToSearchHeaderIn = dec.getContainer();
    }

    if (containerToSearchHeaderIn != null) {
      Declaration headerDeclaration = getNativeHeader(containerToSearchHeaderIn, dec.getName());
      if (headerDeclaration == null || !headerDeclaration.isNative()) return null;
      if (backends.header()) {
        referenceable = headerDeclaration;
      } else {
        if (headerDeclaration != null) {
          referenceable = getNativeDeclaration(headerDeclaration, supportedBackends());
        }
      }
    }
    return referenceable;
  }
 public static String[] getAssignableLiterals(Type type, Unit unit) {
   TypeDeclaration dtd = unit.getDefiniteType(type).getDeclaration();
   if (dtd instanceof Class) {
     if (dtd.isInteger()) {
       return new String[] {"0", "1", "2"};
     }
     if (dtd.isByte()) {
       return new String[] {"0.byte", "1.byte"};
     } else if (dtd.isFloat()) {
       return new String[] {"0.0", "1.0", "2.0"};
     } else if (dtd.isString()) {
       return new String[] {"\"\"", "\"\"\"\"\"\""};
     } else if (dtd.isCharacter()) {
       return new String[] {"' '", "'\\n'", "'\\t'"};
     } else {
       return new String[0];
     }
   } else if (dtd instanceof Interface) {
     if (dtd.isIterable()) {
       return new String[] {"{}"};
     } else if (dtd.isSequential() || dtd.isEmpty()) {
       return new String[] {"[]"};
     } else {
       return new String[0];
     }
   } else {
     return new String[0];
   }
 }
 static Tree.CompilationUnit getRootNode(PhasedUnit unit) {
   IEditorPart ce = getCurrentEditor();
   if (ce instanceof CeylonEditor) {
     CeylonEditor editor = (CeylonEditor) ce;
     CeylonParseController cpc = editor.getParseController();
     if (cpc != null) {
       Tree.CompilationUnit rn = cpc.getTypecheckedRootNode();
       if (rn != null) {
         Unit u = rn.getUnit();
         if (u.equals(unit.getUnit())) {
           return rn;
         }
       }
     }
   }
   return unit.getCompilationUnit();
 }
 static String anonFunctionHeader(Type requiredType, Unit unit) {
   StringBuilder text = new StringBuilder();
   text.append("(");
   boolean first = true;
   char c = 'a';
   List<Type> argTypes = unit.getCallableArgumentTypes(requiredType);
   for (Type paramType : argTypes) {
     if (first) {
       first = false;
     } else {
       text.append(", ");
     }
     text.append(paramType.asSourceCodeString(unit)).append(" ").append(c++);
   }
   text.append(")");
   return text.toString();
 }
 static String defaultValue(Unit unit, Type t) {
   if (isTypeUnknown(t)) {
     return "nothing";
   }
   if (unit.isOptionalType(t)) {
     return "null";
   }
   if (t.isTypeAlias() || t.isClassOrInterface() && t.getDeclaration().isAlias()) {
     return defaultValue(unit, t.getExtendedType());
   }
   if (t.isClass()) {
     TypeDeclaration c = t.getDeclaration();
     if (c.equals(unit.getBooleanDeclaration())) {
       return "false";
     } else if (c.equals(unit.getIntegerDeclaration())) {
       return "0";
     } else if (c.equals(unit.getFloatDeclaration())) {
       return "0.0";
     } else if (c.equals(unit.getStringDeclaration())) {
       return "\"\"";
     } else if (c.equals(unit.getByteDeclaration())) {
       return "0.byte";
     } else if (c.equals(unit.getTupleDeclaration())) {
       final int minimumLength = unit.getTupleMinimumLength(t);
       final List<Type> tupleTypes = unit.getTupleElementTypes(t);
       final StringBuilder sb = new StringBuilder();
       for (int i = 0; i < minimumLength; i++) {
         sb.append(sb.length() == 0 ? "[" : ", ");
         Type currentType = tupleTypes.get(i);
         if (unit.isSequentialType(currentType)) {
           currentType = unit.getSequentialElementType(currentType);
         }
         sb.append(defaultValue(unit, currentType));
       }
       sb.append(']');
       return sb.toString();
     } else if (unit.isSequentialType(t)) {
       final StringBuilder sb = new StringBuilder();
       sb.append('[');
       if (!unit.getEmptyType().isSubtypeOf(t)) {
         sb.append(defaultValue(unit, unit.getSequentialElementType(t)));
       }
       sb.append(']');
       return sb.toString();
     } else if (unit.isIterableType(t)) {
       final StringBuilder sb = new StringBuilder();
       sb.append('{');
       if (!unit.getEmptyType().isSubtypeOf(t)) {
         sb.append(defaultValue(unit, unit.getIteratedType(t)));
       }
       sb.append('}');
       return sb.toString();
     } else {
       return "nothing";
     }
   } else {
     return "nothing";
   }
 }