class PsseImporter implements Importer {

    @Override
    public Network importData(ReadOnlyDataSource dataSource, NetworkFactory networkFactory, Properties parameters) {
        Objects.requireNonNull(dataSource);
        Objects.requireNonNull(networkFactory);

        Network network = networkFactory.createNetwork(dataSource.getBaseName(), FORMAT);

        try {
            String ext = findExtension(dataSource, true);
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(dataSource.newInputStream(null, ext)))) {

                // parse file
                PsseRawModel psseModel = new PsseRawReader().read(reader);

                // check version
                if (psseModel.getCaseIdentification().getRev() > PsseConstants.SUPPORTED_VERSION) {
                    throw new PsseException("PSS/E version higher than " + PsseConstants.SUPPORTED_VERSION + " not supported");
                }
                if (psseModel.getCaseIdentification().getIc() == 1) {
                    throw new PsseException("Incremental load of PSS/E data option (IC = 1) not supported");
                }

                // set date and time
                // TODO

                // build container to fit IIDM requirements
                List<Object> branches = ImmutableList.builder()
                        .addAll(psseModel.getNonTransformerBranches())
                        .addAll(psseModel.getTransformers())
                        .build();
                ToIntFunction<Object> branchToNum1 = branch -> branch instanceof PsseNonTransformerBranch ? ((PsseNonTransformerBranch) branch).getI() : ((PsseTransformer) branch).getFirstRecord().getI();
                ToIntFunction<Object> branchToNum2 = branch -> branch instanceof PsseNonTransformerBranch ? ((PsseNonTransformerBranch) branch).getJ() : ((PsseTransformer) branch).getFirstRecord().getJ();
                ToIntFunction<Object> branchToNum3 = branch -> branch instanceof PsseNonTransformerBranch ? 0 : ((PsseTransformer) branch).getFirstRecord().getK();
                ToDoubleFunction<Object> branchToResistance = branch -> branch instanceof PsseNonTransformerBranch ? ((PsseNonTransformerBranch) branch).getR() : ((PsseTransformer) branch).getSecondRecord().getR12();
                ToDoubleFunction<Object> branchToReactance = branch -> branch instanceof PsseNonTransformerBranch ? ((PsseNonTransformerBranch) branch).getX() : ((PsseTransformer) branch).getSecondRecord().getX12();
                Predicate<Object> branchToIsTransformer = branch -> branch instanceof PsseTransformer;
                ContainersMapping containerMapping = ContainersMapping.create(psseModel.getBuses(), branches, PsseBus::getI, branchToNum1,
                    branchToNum2, branchToNum3, branchToResistance, branchToReactance, branchToIsTransformer,
                    busNums -> "VL" + busNums.iterator().next(), substationNum -> "S" + substationNum++);

                boolean ignoreBaseVoltage = ConversionParameters.readBooleanParameter(FORMAT, parameters, IGNORE_BASE_VOLTAGE_PARAMETER,
                        ParameterDefaultValueConfig.INSTANCE);
                PerUnitContext perUnitContext = new PerUnitContext(psseModel.getCaseIdentification().getSbase(), ignoreBaseVoltage);

                //The map gives access to PsseBus object with the int bus Number
                Map<Integer, PsseBus> busNumToPsseBus = new HashMap<>();

                // create buses
                createBuses(psseModel, containerMapping, perUnitContext, network, busNumToPsseBus);

                //Create loads
                for (PsseLoad psseLoad : psseModel.getLoads()) {
                    createLoad(psseLoad, containerMapping, network);
                }

                //Create fixed shunts
                for (PsseFixedShunt psseShunt : psseModel.getFixedShunts()) {
                    createShuntCompensator(psseShunt, containerMapping, network);
                }

                //Create switched shunts
                Map<PsseSwitchedShunt, ShuntBlockTab > stoBlockiTab = new HashMap<>();
                createSwitchedShuntBlockMap(psseModel, stoBlockiTab);
                for (PsseSwitchedShunt psseSwShunt : psseModel.getSwitchedShunts()) {
                    createSwitchedShunt(psseSwShunt, perUnitContext, containerMapping, network, stoBlockiTab);
                }

                for (PsseGenerator psseGen : psseModel.getGenerators()) {
                    createGenerator(psseGen, busNumToPsseBus.get(psseGen.getI()), containerMapping, network);
                }

                for (PsseNonTransformerBranch psseLine : psseModel.getNonTransformerBranches()) {
                    createLine(psseLine, containerMapping, perUnitContext, network);
                }

                for (PsseTransformer psseTfo : psseModel.getTransformers()) {
                    createTransformer(psseTfo, containerMapping, perUnitContext, network, busNumToPsseBus, psseModel.getCaseIdentification().getSbase());
                }

                // Attach a slack bus
                for (PsseArea psseArea : psseModel.getAreas()) {
                    if (psseArea.getIsw() != 0) {
                        String busId = getBusId(psseArea.getIsw());
                        Bus bus = network.getBusBreakerView().getBus(busId);
                        SlackTerminal.attach(bus);
                    }
                }

                return network;
            }
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

}