public static MacroTransition CreateSingleMacroTransition ( TmDefinition def, State q, byte readPacked, bool facingRight, MacroPacker packerInfo) { if (def == null) throw new ArgumentNullException (); if (q == null) throw new ArgumentNullException (); if (packerInfo == null) throw new ArgumentNullException (); var readUnpacked = packerInfo.Decode (readPacked); var left = facingRight ? new byte[0] : readUnpacked.SubArray (0, readUnpacked.Length - 1); var right = facingRight ? readUnpacked : readUnpacked.SubArray (readUnpacked.Length - 1, 1); var tape = new LimitedBasicTape (left, right, def.Gamma); short dir; var tm = new SimpleTmRun (def, tape, new LimitedBasicTape (tape, def.Gamma), q); tm.AfterStep += new DetectTapeTooSmall ().Detect; tm.Options.AllowCreateMissingTransitionBranches = false; try { TmPrintOptions.Push (); TmPrintOptions.PrintTapeSteps = false; TmPrintOptions.PrintTransitionLevel = PrintTransitionLevel.None; var prevPos = (short) tape.Position; tm.Run (); dir = (short) (tape.Position - prevPos); } catch (TransitionNotDefinedException) { // Intentional throw. Let the caller handle this. throw; } finally { TmPrintOptions.Pop (); } Debug.Assert (tm.Result.Halted.HasValue != tape.ExitsOnLeftSide.HasValue); if (tm.Result.Halted == false) { return new MacroTransition (q, readPacked, facingRight, null, readPacked, 0, tm.Shifts, readUnpacked, readUnpacked); } else { var writeUnpacked = tape.Tape; var writePacked = packerInfo.Encode (writeUnpacked); return new MacroTransition (q, readPacked, facingRight, tm.Q, writePacked, dir, tm.Shifts, readUnpacked, writeUnpacked); } }