// Path: src/main/java/org/jasome/input/Package.java
// public class Package extends Code {
//     private Map<String, Type> typeLookup;
// 
//     public Package(String name) {
//         super(name);
//         typeLookup = new HashMap<>();
//     }
// 
//     @SuppressWarnings("unchecked")
//     public Set<Type> getTypes() {
//         return (Set<Type>)(Set<?>)getChildren();
//     }
// 
//     public void addType(Type type) {
//         typeLookup.put(type.getName(), type);
//         addChild(type);
//     }
// 
//     public Project getParentProject() {
//         return (Project)getParent();
//     }
// 
//     @Override
//     public String toString() {
//         return "Package("+this.getName()+")";
//     }
// 
//     public Optional<Type> lookupTypeByName(String typeName) {
//         if(typeLookup.containsKey(typeName)) {
//             return Optional.of(typeLookup.get(typeName));
//         } else {
//             return Optional.empty();
//         }
//     }
// }
// 
// Path: src/main/java/org/jasome/metrics/Metric.java
// public class Metric {
//     private String name;
//     private String description;
//     private NumericValue value;
// 
//     protected Metric(String name, String description, NumericValue value) {
//         this.name = name;
//         this.description = description;
//         this.value = value;
//     }
// 
//     public static Metric of(String name, String description, NumericValue value) {
//         return new Metric(name, description, value);
//     }
//     
//     public static Metric of(String name, String description, long value) {
//         return new Metric(name, description, NumericValue.of(value));
//     }
// 
//     public static Metric of(String name, String description, double value) {
//         return new Metric(name, description, NumericValue.of(value));
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public String getDescription() {
//         return description;
//     }
// 
//     public NumericValue getValue() {
//         return value;
//     }
//     
//     @Override
//     public String toString() {
//         return name + ": " + value;
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (!(o instanceof Metric)) return false;
//         Metric that = (Metric) o;
//         return Objects.equal(name, that.name) &&
//                 Objects.equal(description, that.description) &&
//                 Objects.equal(value, that.value);
//     }
// 
//     @Override
//     public int hashCode() {
//         return Objects.hashCode(name, description, value);
//     }
// 
//     public String getFormattedValue() {
//         return value.toString();
//     }
// }


import org.jasome.input.*;
import org.jasome.input.Package;
import org.jasome.metrics.Metric;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;
                }
            }

            return doc;

        } catch (ParserConfigurationException e) {
            throw new RuntimeException(e);
        }

    }

    private <T extends Code> List<T> sortChildren(Collection<T> children) {
        return children.stream().sorted(new Comparator<Code>() {
            @Override
            public int compare(Code o1, Code o2) {
                return o1.getName().compareTo(o2.getName());
            }

        }).collect(Collectors.toList());
    }

    private void addAttributes(Code classNode, Element classElement) {
        for (Map.Entry<String, String> attribute : classNode.getAttributes().entrySet()) {
            classElement.setAttribute(attribute.getKey(), attribute.getValue());
        }
    }

    private void addMetricsForNode(Document doc, Node parentElement, Code node) {
        Element metricsContainer = doc.createElement("Metrics");

// Path: src/main/java/org/jasome/input/Package.java
// public class Package extends Code {
//     private Map<String, Type> typeLookup;
// 
//     public Package(String name) {
//         super(name);
//         typeLookup = new HashMap<>();
//     }
// 
//     @SuppressWarnings("unchecked")
//     public Set<Type> getTypes() {
//         return (Set<Type>)(Set<?>)getChildren();
//     }
// 
//     public void addType(Type type) {
//         typeLookup.put(type.getName(), type);
//         addChild(type);
//     }
// 
//     public Project getParentProject() {
//         return (Project)getParent();
//     }
// 
//     @Override
//     public String toString() {
//         return "Package("+this.getName()+")";
//     }
// 
//     public Optional<Type> lookupTypeByName(String typeName) {
//         if(typeLookup.containsKey(typeName)) {
//             return Optional.of(typeLookup.get(typeName));
//         } else {
//             return Optional.empty();
//         }
//     }
// }
// 
// Path: src/main/java/org/jasome/metrics/Metric.java
// public class Metric {
//     private String name;
//     private String description;
//     private NumericValue value;
// 
//     protected Metric(String name, String description, NumericValue value) {
//         this.name = name;
//         this.description = description;
//         this.value = value;
//     }
// 
//     public static Metric of(String name, String description, NumericValue value) {
//         return new Metric(name, description, value);
//     }
//     
//     public static Metric of(String name, String description, long value) {
//         return new Metric(name, description, NumericValue.of(value));
//     }
// 
//     public static Metric of(String name, String description, double value) {
//         return new Metric(name, description, NumericValue.of(value));
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public String getDescription() {
//         return description;
//     }
// 
//     public NumericValue getValue() {
//         return value;
//     }
//     
//     @Override
//     public String toString() {
//         return name + ": " + value;
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (!(o instanceof Metric)) return false;
//         Metric that = (Metric) o;
//         return Objects.equal(name, that.name) &&
//                 Objects.equal(description, that.description) &&
//                 Objects.equal(value, that.value);
//     }
// 
//     @Override
//     public int hashCode() {
//         return Objects.hashCode(name, description, value);
//     }
// 
//     public String getFormattedValue() {
//         return value.toString();
//     }
// }


// Path: src/main/java/org/jasome/output/XMLOutputter.java
import org.jasome.input.*;
import org.jasome.input.Package;
import org.jasome.metrics.Metric;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

                }
            }

            return doc;

        } catch (ParserConfigurationException e) {
            throw new RuntimeException(e);
        }

    }

    private <T extends Code> List<T> sortChildren(Collection<T> children) {
        return children.stream().sorted(new Comparator<Code>() {
            @Override
            public int compare(Code o1, Code o2) {
                return o1.getName().compareTo(o2.getName());
            }

        }).collect(Collectors.toList());
    }

    private void addAttributes(Code classNode, Element classElement) {
        for (Map.Entry<String, String> attribute : classNode.getAttributes().entrySet()) {
            classElement.setAttribute(attribute.getKey(), attribute.getValue());
        }
    }

    private void addMetricsForNode(Document doc, Node parentElement, Code node) {
        Element metricsContainer = doc.createElement("Metrics");

        Set<Metric> metrics = node.getMetrics();