public static function DO2Array(DataObject $do, $depth = 1, $exclude = array(), $include = array(), $currentDepth = 0)
 {
     $out = array();
     // Look for includes and excludes on object
     $inclExists = $exclExists = true;
     try {
         $do->getIncludeInDump();
     } catch (Exception $e) {
         $inclExists = false;
     }
     try {
         $do->getExcludeFromDump();
     } catch (Exception $e) {
         $exclExists = false;
     }
     // Process Incl + Excl
     $includeInDump = $inclExists ? $do->getIncludeInDump() : array();
     $excludeFromDump = $exclExists ? $do->getExcludeFromDump() : array();
     $includeInDump = array_unique(array_merge($include, !empty($includeInDump) && is_array($includeInDump) ? $includeInDump : array()));
     $excludeFromDump = array_unique(array_merge($exclude, !empty($excludeFromDump) && is_array($excludeFromDump) ? $excludeFromDump : array()));
     // Fields on Obj
     foreach (self::getFieldsForObj($do) as $fieldName => $fieldType) {
         if (!in_array($fieldName, $excludeFromDump)) {
             $out[$fieldName] = $do->{$fieldName};
         }
     }
     // inclusion
     foreach ($includeInDump as $incl) {
         $tmp = null;
         try {
             $tmp = $do->{$incl}();
         } catch (Exception $e) {
             try {
                 $method = 'get' . ucfirst($incl);
                 $tmp = $do->{$method}();
             } catch (Exception $e) {
                 $tmp = $do->{$incl};
             }
         }
         if ($tmp && is_object($tmp) && is_a($tmp, 'DataObjectSet')) {
             if ($depth > $currentDepth) {
                 $r = array();
                 foreach ($tmp as $item) {
                     $r[] = self::DO2Array($item, $depth, $exclude, $include, $currentDepth + 1);
                 }
                 $out[$incl] = $r;
             }
         } elseif ($tmp && is_object($tmp) && is_a($tmp, 'DataObject')) {
             $out[$incl] = self::DO2Array($tmp, $depth, $exclude, $include, $currentDepth + 1);
         } elseif ($tmp) {
             $out[$incl] = $tmp;
         }
     }
     // Relations
     if ($depth > $currentDepth) {
         if ($do->has_many()) {
             foreach ($do->has_many() as $k => $v) {
                 if (!in_array($k, $excludeFromDump)) {
                     $r = array();
                     foreach ($do->{$k}() as $childK => $childV) {
                         $r[] = self::DO2Array($childV, $depth, $exclude, $include, $currentDepth + 1);
                     }
                     $out[$k] = $r;
                 }
             }
         }
         if ($do->has_one()) {
             foreach ($do->has_one() as $k => $v) {
                 if (!in_array($k, $excludeFromDump)) {
                     $out[$k] = self::DO2Array($do->{$k}(), $depth, $exclude, $include, $currentDepth + 1);
                 }
             }
         }
         if ($do->many_many()) {
             foreach ($do->many_many() as $k => $v) {
                 if (!in_array($k, $excludeFromDump)) {
                     $r = array();
                     foreach ($do->{$k}() as $childK => $childV) {
                         $r[] = self::DO2Array($childV, $depth, $exclude, $include, $currentDepth + 1);
                     }
                     $out[$k] = $r;
                 }
             }
         }
     }
     return $out;
 }