package com.btk5h.skriptmirror.skript;

import com.btk5h.skriptmirror.Util;

import org.bukkit.event.Event;

import ch.njol.skript.Skript;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.ExpressionType;
import ch.njol.skript.lang.SkriptParser;
import ch.njol.skript.lang.util.SimpleExpression;
import ch.njol.util.Kleenean;

public class ExprCollect extends SimpleExpression<Object> {
  static {
    Skript.registerExpression(ExprCollect.class, Object.class, ExpressionType.COMBINED,
        "\\[%objects%\\]");
  }

  private Expression<Object> objects;

  @Override
  protected Object[] get(Event e) {
    return new Object[]{objects.getArray(e)};
  }

  @Override
  public boolean isSingle() {
    return true;
  }

  @Override
  public Class<?> getReturnType() {
    return Object.class;
  }

  @Override
  public String toString(Event e, boolean debug) {
    return "array of " + objects.toString(e, debug);
  }

  @SuppressWarnings("unchecked")
  @Override
  public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed,
                      SkriptParser.ParseResult parseResult) {
    objects = Util.defendExpression(exprs[0]);
    return Util.canInitSafely(objects);
  }
}

@@ -67,44 +67,133 @@
 ror.
-Util;%0A%0Aimport org.bukkit.event.Event
+Null;%0Aimport com.btk5h.skriptmirror.Util;%0A%0Aimport org.bukkit.event.Event;%0A%0Aimport java.util.Arrays;%0Aimport java.util.Optional
 ;%0A%0Ai
@@ -712,48 +712,851 @@
     
-return new Object%5B%5D%7Bobjects.getArray(e)%7D
+Object%5B%5D items = objects.getArray(e);%0A    Object%5B%5D castedItems = Util.newArray(getCommonSuperclass(items), items.length);%0A%0A    System.arraycopy(items, 0, castedItems, 0, items.length);%0A%0A    return new Object%5B%5D%7BcastedItems%7D;%0A  %7D%0A%0A  private static Class%3C?%3E getCommonSuperclass(Object%5B%5D objects) %7B%0A    Optional%3CObject%3E firstNonnull = Arrays.stream(objects)%0A        .filter(o -%3E o != Null.getInstance())%0A        .findFirst();%0A%0A    if (firstNonnull.isPresent()) %7B%0A      return Arrays.stream(objects)%0A          .map(Object::getClass)%0A          .map(o -%3E (Class) o)%0A          .reduce(firstNonnull.get().getClass(), ExprCollect::getCommonSuperclass);%0A    %7D%0A%0A    return Object.class;%0A  %7D%0A%0A  private static Class%3C?%3E getCommonSuperclass(Class%3C?%3E c1, Class%3C?%3E c2) %7B%0A    while (!c1.isAssignableFrom(c2)) %7B%0A      c1 = c1.getSuperclass();%0A    %7D%0A    return c1
 ;%0A  

Return the most specific array when collecting an array (fixes #39)