/// <summary>
        /// Sample implementation of end-to-end electronic structure problem simulation.
        /// </summary>
        /// <param name="filename"></param>
        public static void SampleWorkflow(
            string filename,
            string wavefunctionLabel,
            IndexConvention indexConvention
            )
        {
            // Deserialize Broombridge from file.
            Data broombridge = Deserializers.DeserializeBroombridge(filename);

            // A single file can contain multiple problem descriptions. Let us pick the first one.
            var problemData = broombridge.ProblemDescriptions.First();

            #region Create electronic structure Hamiltonian
            // Electronic structure Hamiltonians are usually represented compactly by orbital integrals. Let us construct
            // such a Hamiltonian from broombridge.
            OrbitalIntegralHamiltonian orbitalIntegralHamiltonian = problemData.OrbitalIntegralHamiltonian;

            // We can obtain the full fermion Hamiltonian from the more compact orbital integral representation.
            // This transformation requires us to pick a convention for converting a spin-orbital index to a single integer.
            // Let us pick one according to the formula `integer = 2 * orbitalIndex + spinIndex`.
            FermionHamiltonian fermionHamiltonian = orbitalIntegralHamiltonian.ToFermionHamiltonian(indexConvention);

            // We target a qubit quantum computer, which requires a Pauli representation of the fermion Hamiltonian.
            // A number of mappings from fermions to qubits are possible. Let us choose the Jordan–Wigner encoding.
            PauliHamiltonian pauliHamiltonian = fermionHamiltonian.ToPauliHamiltonian(QubitEncoding.JordanWigner);
            #endregion

            #region Create wavefunction Ansatzes
            // A list of trial wavefunctions can be provided in the Broombridge file. For instance, the wavefunction
            // may be a single-reference Hartree--Fock state, a multi-reference state, or a unitary coupled-cluster state.
            // In this case, Broombridge indexes the fermion operators with spin-orbitals instead of integers.
            Dictionary <string, FermionWavefunction <SpinOrbital> > inputStates = problemData.Wavefunctions ?? new Dictionary <string, FermionWavefunction <SpinOrbital> >();

            // If no states are provided, use the Hartree--Fock state.
            // As fermion operators the fermion Hamiltonian are already indexed by, we now apply the desired
            // spin-orbital -> integer indexing convention.
            FermionWavefunction <int> inputState = inputStates.ContainsKey(wavefunctionLabel)
                ? inputStates[wavefunctionLabel].ToIndexing(indexConvention)
                : fermionHamiltonian.CreateHartreeFockState(problemData.NElectrons);
            #endregion

            #region Pipe to QSharp and simulate
            // We now convert this Hamiltonian and a selected state to a format that than be passed onto the QSharp component
            // of the library that implements quantum simulation algorithms.
            var qSharpHamiltonian  = pauliHamiltonian.ToQSharpFormat();
            var qSharpWavefunction = inputState.ToQSharpFormat();
            var qSharpData         = QSharpFormat.Convert.ToQSharpFormat(qSharpHamiltonian, qSharpWavefunction);
            #endregion
        }
        /// <summary>
        ///      Loads a Hamiltonian from integral data represented
        ///      in LIQ𝑈𝑖|⟩ format.
        ///      Please see the <a href="https://stationq.github.io/Liquid/docs/LIQUiD.pdf">
        ///      LIQ𝑈𝑖|⟩ documentation</a> for further details about the
        ///      format parsed by this method.
        /// </summary>
        /// <param name="lines">Sequence of text describing terms of Hamiltonian.</param>
        /// <returns>
        ///      An instance of <see cref="FermionHamiltonian"/> representing the
        ///      data contained in <paramref name="lines"/>.
        /// </returns>
        public static FermionHamiltonian LoadFromLiquid(string line)
        {
            var regexMiscellaneous = new Regex(@"((info=(?<info>[^\s]*)))");
            var regexnuc           = new Regex(@"nuc=(?<nuc>-?\s*\d*.\d*)");
            var regexPQ            = new Regex(@"(^|\s+)(?<p>\d+),(?<q>\d+)\D*=\s*(?<coeff>-?\s*\d*.\d*)e?(?<exponent>-?\d*)");
            var regexPQRS          = new Regex(@"(^|\s+)(?<p>\d+)\D+(?<q>\d+)\D+(?<r>\d+)\D+(?<s>\d+)\D*=\s*(?<coeff>-?\s*\d*.\d*)e?(?<exponent>-?\d*)");

            Double coulombRepulsion = 0.0;
            var    fileHIJTerms     = new Dictionary <Int64[], Double>(new Extensions.IntArrayIEqualityComparer());
            var    fileHIJKLTerms   = new Dictionary <Int64[], Double>(new Extensions.IntArrayIEqualityComparer());
            var    hamiltonian      = new FermionHamiltonian();

            var nOrbitals = 0L;

            Match stringMisc = regexMiscellaneous.Match(line);

            if (stringMisc.Success)
            {
                hamiltonian.MiscellaneousInformation = stringMisc.Groups["info"].ToString();
            }

            Match stringnuc = regexnuc.Match(line);

            if (stringnuc.Success)
            {
                hamiltonian.EnergyOffset = Double.Parse(stringnuc.Groups["nuc"].ToString());
            }
            foreach (Match stringPQ in regexPQ.Matches(line))
            {
                if (stringPQ.Success)
                {
                    var p              = Int64.Parse(stringPQ.Groups["p"].ToString());
                    var q              = Int64.Parse(stringPQ.Groups["q"].ToString());
                    var coeff          = Double.Parse(stringPQ.Groups["coeff"].ToString());
                    var exponentString = stringPQ.Groups["exponent"].ToString();
                    var exponent       = 0.0;
                    if (exponentString != "")
                    {
                        exponent = Double.Parse(stringPQ.Groups["exponent"].ToString());
                    }
                    nOrbitals = new long[] { nOrbitals, p + 1, q + 1 }.Max();

                    var orbitalIntegral          = new OrbitalIntegral(new Int64[] { p, q }, coeff * (10.0).Pow(exponent));
                    var orbitalIntegralCanonical = orbitalIntegral.ToCanonicalForm();

                    //Logger.Message.WriteLine($"1e orbital { orbitalIntegral.Print()}, { orbitalIntegralCanonical.Print()}");

                    if (fileHIJTerms.ContainsKey(orbitalIntegralCanonical.OrbitalIndices))
                    {
                        // Check consistency
                        if (fileHIJTerms[orbitalIntegralCanonical.OrbitalIndices] != orbitalIntegral.Coefficient)
                        {
                            // Consistency check failed.
                            throw new System.NotSupportedException(
                                      $"fileHPQTerm Consistency check fail. " +
                                      $"Orbital integral {orbitalIntegral} coefficient {orbitalIntegral.Coefficient}" +
                                      $"does not match recorded {orbitalIntegralCanonical} coefficient {fileHIJTerms[orbitalIntegral.OrbitalIndices]}.");
                        }
                        else
                        {
                            // Consistency check passed.
                        }
                        //Logger.Message.WriteLine($"1e orbital collision { orbitalIntegral.Print()}, { orbitalIntegralCanonical.Print()}");
                    }
                    else
                    {
                        fileHIJTerms.Add(orbitalIntegralCanonical.OrbitalIndices, orbitalIntegralCanonical.Coefficient);
                    }
                }
            }
            foreach (Match stringPQRS in regexPQRS.Matches(line))
            {
                if (stringPQRS.Success)
                {
                    var p              = Int64.Parse(stringPQRS.Groups["p"].ToString());
                    var q              = Int64.Parse(stringPQRS.Groups["q"].ToString());
                    var r              = Int64.Parse(stringPQRS.Groups["r"].ToString());
                    var s              = Int64.Parse(stringPQRS.Groups["s"].ToString());
                    var coeff          = Double.Parse(stringPQRS.Groups["coeff"].ToString());
                    var exponentString = stringPQRS.Groups["exponent"].ToString();
                    var exponent       = 0.0;
                    if (exponentString != "")
                    {
                        exponent = Double.Parse(stringPQRS.Groups["exponent"].ToString());
                    }
                    nOrbitals = new long[] { nOrbitals, p + 1, q + 1, r + 1, s + 1 }.Max();

                    var orbitalIntegral          = new OrbitalIntegral(new Int64[] { p, q, r, s }, coeff * (10.0).Pow(exponent));
                    var orbitalIntegralCanonical = orbitalIntegral.ToCanonicalForm();

                    //Logger.Message.WriteLine($"2e orbital: { orbitalIntegral.Print()}, { orbitalIntegralCanonical.Print()}");

                    if (fileHIJKLTerms.ContainsKey(orbitalIntegralCanonical.OrbitalIndices))
                    {
                        // Check consistency
                        if (fileHIJKLTerms[orbitalIntegralCanonical.OrbitalIndices] != orbitalIntegral.Coefficient)
                        {
                            // Consistency check failed.
                            throw new System.NotSupportedException(
                                      $"fileHPQRSTerm Consistency check fail. " +
                                      $"Orbital integral {orbitalIntegral.OrbitalIndices} coefficient {orbitalIntegral.Coefficient}" +
                                      $"does not match recorded {orbitalIntegralCanonical.OrbitalIndices} coefficient {fileHIJKLTerms[orbitalIntegral.OrbitalIndices]}.");
                        }
                        else
                        {
                            // Consistency check passed.
                        }
                        //Logger.Message.WriteLine($"2e orbital collision { orbitalIntegral.Print()}, { orbitalIntegralCanonical.Print()}");
                    }
                    else
                    {
                        fileHIJKLTerms.Add(orbitalIntegralCanonical.OrbitalIndices, orbitalIntegralCanonical.Coefficient);
                    }
                }
            }

            hamiltonian.NOrbitals = nOrbitals;
            foreach (var ijTerm in fileHIJTerms)
            {
                hamiltonian.AddFermionTerm(new OrbitalIntegral(ijTerm.Key, ijTerm.Value));
            }
            foreach (var ijklTerm in fileHIJKLTerms)
            {
                hamiltonian.AddFermionTerm(new OrbitalIntegral(ijklTerm.Key, ijklTerm.Value));
            }
            hamiltonian.SortAndAccumulate();
            return(hamiltonian);
        }