package org.smoothbuild.lang.type;

import static com.google.common.collect.Sets.newHashSet;
import static java.lang.Math.max;
import static java.util.stream.Collectors.toList;
import static org.smoothbuild.lang.type.ArrayType.arrayWithDepth;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class TypeHierarchy {

  /**
   * @return types sorted using type - subtype relationship. Each type comes before all of its
   *         subtypes.
   */
  public static List<Type> sortedTypes(Iterable<? extends Type> types) {
    Set<Type> uniqueTypes = newHashSet(types);
    List<Type> sorted = new ArrayList<>();
    Set<Type> alreadySorted = new HashSet<>();
    int nothingMaxDepth = -1;
    Type nothing = null;
    for (Type type : uniqueTypes) {
      if (type.coreType().isNothing()) {
        nothingMaxDepth = max(nothingMaxDepth, type.coreDepth());
        nothing = type.coreType();
      } else {
        for (Type t : type.hierarchy()) {
          if (!alreadySorted.contains(t)) {
            sorted.add(t);
            alreadySorted.add(t);
          }
        }
      }
    }
    for (int i = nothingMaxDepth; 0 <= i; i--) {
      sorted.add(arrayWithDepth(nothing, i));
    }
    return sorted
        .stream()
        .filter(t -> uniqueTypes.contains(t))
        .collect(toList());
  }
}

@@ -109,137 +109,37 @@
 ava.
-lang.Math.max;%0Aimport static java.util.stream.Collectors.toList;%0Aimport static org.smoothbuild.lang.type.ArrayType.arrayWithDepth
+util.stream.Collectors.toList
 ;%0A%0Ai
@@ -611,38 +611,8 @@
 ();%0A
-    int nothingMaxDepth = -1;%0A
     
@@ -623,16 +623,21 @@
  nothing
+Array
  = null;
@@ -726,46 +726,62 @@
     
+if (
 nothing
-MaxDepth = max(nothingMax
+Array == null %7C%7C nothingArray.core
 Depth
-,
+() %3C
  typ
@@ -794,26 +794,28 @@
 Depth())
-;%0A
+ %7B%0A 
         
 nothing 
@@ -810,34 +810,39 @@
     
+ 
 nothing
+Array
  = type
-.coreType();
+;%0A        %7D
 %0A   
@@ -1044,53 +1044,88 @@
     
-for (int i = nothingMaxDepth; 0 %3C= i; i--
+if (nothingArray != null) %7B%0A      while (nothingArray instanceof ArrayType
 ) %7B%0A
+  
     
@@ -1141,30 +1141,117 @@
 add(
-arrayWithDepth
+nothingArray);%0A        nothingArray = ((ArrayType) nothingArray).elemType();%0A      %7D%0A      sorted.add
 (nothing
 , i)
@@ -1250,12 +1250,13 @@
 hing
-, i)
+Array
 );%0A 

refactor TypeHierarchy to not use ArrayType.arrayWithDepth()