public override bool Read(GH_IO.Serialization.GH_IReader reader)
        {
            // 2013 Oct 8 - Giulio
              // Removing all hacks and making this work properly from Gh 0.9.61 onwards
              // The logic is this: this component ALWAYS gets constructed without "code" & with "out".
              // Then, when they are not necessary, these are added or removed.
              // RegisterInput/Output must always insert the original amount of items.

              if (reader.ItemExists(ID_EditorLocation))
            DefaultEditorLocation = reader.GetDrawingPoint(ID_EditorLocation);
              if (reader.ItemExists(ID_EditorSize))
            DefaultEditorSize = reader.GetDrawingSize(ID_EditorSize);

              bool hideInput = true;
              if (reader.TryGetBoolean(ID_HideInput, ref hideInput))
            HiddenCodeInput = hideInput;

              bool hideOutput = false;
              if (reader.TryGetBoolean(ID_HideOutput, ref hideOutput))
            HiddenOutOutput = hideOutput;

              if (hideInput)
            if (!reader.TryGetString(ID_CodeInput, ref m_inner_codeInput))
              m_inner_codeInput = string.Empty;

              bool rc = base.Read(reader);

              // Dynamic input fix for existing scripts
              // Always assign DynamicHint or Grasshopper
              // will set Line and not LineCurve, etc...
              if (Params != null && Params.Input != null)
              {
            for (int i = HiddenCodeInput ? 1 : 0; i < Params.Input.Count; i++)
            {
              var p = Params.Input[i] as Param_ScriptVariable;
              if (p != null)
              {
            FixGhInput(p, false);
            if (p.TypeHint == null)
            {
              p.TypeHint = p.Hints[0];
            }
              }
            }
              }
              return rc;
        }
        public override bool Read(GH_IO.Serialization.GH_IReader reader)
        {
            // 8 Aug. 2012
              // There are a couple of "hacks" in here to get IO code to work properly.
              // I'll discuss fixes for this so we can skip over the code in future
              // versions of grasshopper

              bool perform_hacks = this is IGH_VarParamComponent;
              if (perform_hacks)
              {
            // only perform these hacks on 0.9.6 and below. Assuming that this
            // will get fixed in the very next GH release
            var version = Grasshopper.Versioning.Version;
            if (version.major > 0 || version.minor > 9 || (version.minor == 9 && version.revision > 6))
              perform_hacks = false;
              }

              if( perform_hacks )
              {
            // Hack #1
            // When deserializing, this component is constructed and the I can't tell
            // that this component was created for deserializing from disk and the
            // "AddDefaultInput" / "AddDefaultOutput" functions are called. The low level
            // parameter reading code skips reading of params when they already exists
            // (see Read_IGH_VarParamParamList in GH_ComponentParamServer.vb)
            //   ... If (i<params.Count) Then Continue For
            // Clear out the default input parameters so the GH variable
            // parameter reader doesn't get hosed
            for (int i = Params.Input.Count - 1; i >= 0; i--)
              Params.UnregisterParameter(Params.Input[0]);
            for (int i = Params.Output.Count - 1; i >= 0; i--)
              Params.UnregisterParameter(Params.Output[0]);
              }

              bool rc = base.Read(reader);

              if (perform_hacks)
              {
            // Hack #2
            // The IO code in checks to see if "Access" exists when it looks like
            // it should be checking if "Access" at index exists
            // (see Read_IGH_VarParamParamList in GH_ComponentParamServer.vb)
            //   ...If( reader.ItemExists("Access")) Then
            //   probably should be
            //   ...If( reader.ItemExists("Access", i)) Then
            //
            // Working around this issue by manually digging through the chuncks
            if (reader.ChunkCount > 1)
            {
              var chunk = reader.Chunks[1];
              for (int i = 0; i < chunk.ItemCount; i++)
              {
            var item = chunk.Items[i];
            if (item != null && string.Compare(item.Name, "Access", StringComparison.InvariantCulture) == 0)
            {
              int index = item.Index;
              if (index >= 0 && index < Params.Input.Count)
              {
                int access = item._int32;
                if (1 == access)
                  Params.Input[index].Access = GH_ParamAccess.list;
                else if (2 == access)
                  Params.Input[index].Access = GH_ParamAccess.tree;
              }
            }
              }
            }
              }

              bool hideInput = false;
              if (reader.TryGetBoolean(HideInputIdentifier, ref hideInput))
            CodeInputVisible = !hideInput;

              if (!CodeInputVisible)
              {
            string code = null;
            if (reader.TryGetString(CodeInputIdentifier, ref code))
              CodeInput = code;
              }

              bool hideOutput = false;
              if (reader.TryGetBoolean(HideOutputIdentifier, ref hideOutput))
            HideCodeOutput = hideOutput;

              if (HideCodeOutput)
            Params.Output.RemoveAt(0);

              // Dynamic input fix for existing scripts
              // Always assign DynamicHint or Grasshopper
              // will set Line and not LineCurve, etc...
              if (Params != null && Params.Input != null)
              {
            for (int i = CodeInputVisible ? 1 : 0; i < Params.Input.Count; i++)
            {
              var p = Params.Input[i] as Param_ScriptVariable;
              if (p != null)
              {
            FixGhInput(p, false);
            if (p.TypeHint == null)
            {
              p.TypeHint = p.Hints[0];
            }
              }
            }
              }
              return rc;
        }