/*
         * Create a generic-purpose reference.
         */
        private ITES5Referencer CreateReference(string referenceName, TES5BasicType?typeForNewProperty, string?tes4ReferenceNameForType, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope, TES5LocalScope localScope)
        {
            if (TES5PlayerReference.EqualsPlayer(referenceName))
            {
                return(CreateReferenceToPlayer(globalScope));
            }

            Match match = ReferenceAndPropertyNameRegex.Match(referenceName);

            if (match.Success)
            {
                TES5ObjectProperty propertyReference = this.objectPropertyFactory.CreateObjectProperty(match.Groups[1].Value, match.Groups[2].Value, this, localScope, globalScope, multipleScriptsScope);
                return(propertyReference);
            }

            ITES5VariableOrProperty?property = localScope.TryGetVariable(referenceName);

            if (property == null)
            {
                property = globalScope.TryGetPropertyByOriginalName(referenceName); //todo rethink how to unify the prefix searching
                if (property == null)
                {
                    Nullable <int> tes4FormID   = null;
                    ITES5Type      propertyType =
                        typeForNewProperty != null ? typeForNewProperty :
                        GetPropertyTypeAndFormID(referenceName, tes4ReferenceNameForType, globalScope, multipleScriptsScope, out tes4FormID);
                    TES5Property propertyToAddToGlobalScope = TES5PropertyFactory.ConstructWithTES4FormID(referenceName, propertyType, referenceName, tes4FormID);
                    globalScope.AddProperty(propertyToAddToGlobalScope);
                    property = propertyToAddToGlobalScope;
                }
            }

            return(CreateReferenceToVariableOrProperty(property));
        }
        public TES5ObjectProperty CreateObjectProperty(string parentReferenceName, string childReferenceName, TES5ReferenceFactory referenceFactory, TES5LocalScope localScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            ITES5Referencer    parentReference = referenceFactory.CreateReference(parentReferenceName, globalScope, multipleScriptsScope, localScope);
            TES5ObjectProperty childReference  = CreateObjectProperty(parentReference, childReferenceName, multipleScriptsScope);//Todo rethink the prefix adding

            return(childReference);
        }
        public TES5ObjectProperty CreateObjectProperty(TES5MultipleScriptsScope multipleScriptsScope, ITES5Referencer reference, string propertyName)
        {
            ITES5VariableOrProperty referencesTo = reference.ReferencesTo;

            this.typeInferencer.InferenceVariableByReferenceEdid(referencesTo, multipleScriptsScope);
            TES5Property       remoteProperty = multipleScriptsScope.GetPropertyFromScript(referencesTo.TES5Type.OriginalName, propertyName);
            TES5ObjectProperty objectProperty = new TES5ObjectProperty(reference, remoteProperty);

            return(objectProperty);
        }
        public TES5ObjectProperty CreateObjectProperty(ITES5Referencer reference, string propertyName, TES5MultipleScriptsScope multipleScriptsScope)
        {
            ITES5VariableOrProperty?referencesTo = reference.ReferencesTo;

            if (referencesTo == null)
            {
                throw new NullableException(nameof(referencesTo));
            }
            this.typeInferencer.InferenceVariableByReferenceEdid(referencesTo, multipleScriptsScope);
            TES5Property       remoteProperty = multipleScriptsScope.GetPropertyFromScript(referencesTo.TES5Type.OriginalName, propertyName);
            TES5ObjectProperty objectProperty = new TES5ObjectProperty(reference, remoteProperty);

            return(objectProperty);
        }
        /*
         * Create a generic-purpose reference.
         */
        public ITES5Referencer CreateReference(string referenceName, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope, TES5LocalScope localScope)
        {
            if (TES5PlayerReference.EqualsPlayer(referenceName))
            {
                return(CreateReferenceToPlayer());
            }

            referenceName = PapyrusCompiler.FixReferenceName(referenceName);
            Match match = PropertyNameRegex.Match(referenceName);

            if (match.Success)
            {
                ITES5Referencer    mainReference     = this.CreateReference(match.Groups[1].Value, globalScope, multipleScriptsScope, localScope);
                TES5ObjectProperty propertyReference = this.objectPropertyFactory.CreateObjectProperty(multipleScriptsScope, mainReference, match.Groups[2].Value); //Todo rethink the prefix adding
                return(propertyReference);
            }

            ITES5VariableOrProperty property = localScope.GetVariable(referenceName);

            if (property == null)
            {
                property = globalScope.GetPropertyByName(referenceName); //todo rethink how to unify the prefix searching
                if (property == null)
                {
                    TES5Property propertyToAddToGlobalScope = null;
                    ITES5Type    specialConversion;
                    if (specialConversions.TryGetValue(referenceName, out specialConversion))
                    {
                        propertyToAddToGlobalScope = new TES5Property(referenceName, specialConversion, referenceName);
                    }

                    if (propertyToAddToGlobalScope == null)
                    {
                        if (!multipleScriptsScope.ContainsGlobalVariable(referenceName))
                        {
                            propertyToAddToGlobalScope = new TES5Property(referenceName, TES5BasicType.T_FORM, referenceName);
                        }
                        else
                        {
                            propertyToAddToGlobalScope = new TES5Property(referenceName, TES5BasicType.T_GLOBALVARIABLE, referenceName);
                        }
                    }
                    globalScope.AddProperty(propertyToAddToGlobalScope);
                    property = propertyToAddToGlobalScope;
                }
            }

            return(new TES5Reference(property));
        }