public void MergeOrigins (UsageVector o_vectors)
			{
				Report.Debug (1, "  MERGING BREAK ORIGINS", this);

				if (o_vectors == null)
					return;

				if (IsUnreachable && locals != null)
					locals.SetAll (true);

				for (UsageVector vector = o_vectors; vector != null; vector = vector.Next) {
					Report.Debug (1, "    MERGING BREAK ORIGIN", vector);
					if (vector.IsUnreachable)
						continue;
					locals &= vector.locals;
					is_unreachable &= vector.is_unreachable;
				}

				Report.Debug (1, "  MERGING BREAK ORIGINS DONE", this);
			}
			public static UsageVector MergeSiblings (UsageVector sibling_list, Location loc)
			{
				if (sibling_list.Next == null)
					return sibling_list;

				MyBitVector locals = null;
				bool is_unreachable = sibling_list.is_unreachable;

				if (!sibling_list.IsUnreachable)
					locals &= sibling_list.locals;

				for (UsageVector child = sibling_list.Next; child != null; child = child.Next) {
					is_unreachable &= child.is_unreachable;

					if (!child.IsUnreachable)
						locals &= child.locals;
				}

				return new UsageVector (locals, is_unreachable, null, loc);
			}
			// <summary>
			//   Merges a child branching.
			// </summary>
			public UsageVector MergeChild (UsageVector child, bool overwrite)
			{
				Report.Debug (2, "    MERGING CHILD EFFECTS", this, child, Type);

				bool new_isunr = child.is_unreachable;

				//
				// We've now either reached the point after the branching or we will
				// never get there since we always return or always throw an exception.
				//
				// If we can reach the point after the branching, mark all locals and
				// parameters as initialized which have been initialized in all branches
				// we need to look at (see above).
				//

				if ((Type == SiblingType.SwitchSection) && !new_isunr) {
					Report.Error (163, Location,
						      "Control cannot fall through from one " +
						      "case label to another");
					return child;
				}

				locals |= child.locals;

				// throw away un-necessary information about variables in child blocks
				if (locals.Count != CountLocals)
					locals = new MyBitVector (locals, CountLocals);

				if (overwrite)
					is_unreachable = new_isunr;
				else
					is_unreachable |= new_isunr;

				return child;
			}
			//
			// Normally, you should not use any of these constructors.
			//
			public UsageVector (SiblingType type, UsageVector parent, Block block, Location loc, int num_locals)
			{
				this.Type = type;
				this.Block = block;
				this.Location = loc;
				this.InheritsFrom = parent;
				this.CountLocals = num_locals;

				locals = num_locals == 0 
					? MyBitVector.Empty
					: new MyBitVector (parent == null ? MyBitVector.Empty : parent.locals, num_locals);

				if (parent != null)
					is_unreachable = parent.is_unreachable;

				id = ++next_id;

			}
			private UsageVector (MyBitVector locals, bool is_unreachable, Block block, Location loc)
			{
				this.Type = SiblingType.Block;
				this.Location = loc;
				this.Block = block;

				this.is_unreachable = is_unreachable;

				this.locals = locals;

				id = ++next_id;

			}
		// <summary>
		//   Performs an `or' operation on the bit vector.  The `new_vector' may have a
		//   different size than the current one.
		// </summary>
		private MyBitVector Or (MyBitVector new_vector)
		{
			if (Count == 0 || new_vector.Count == 0)
				return this;

			var o = new_vector.vector != null ? new_vector.vector : new_vector.shared;

			if (o == null) {
				int n = new_vector.Count;
				if (n < Count) {
					for (int i = 0; i < n; ++i)
						this [i] = true;
				} else {
					SetAll (true);
				}
				return this;
			}

			if (Count == o.Count) {
				if (vector == null) {
					if (shared == null)
						return this;
					initialize_vector ();
				}
				vector.Or (o);
				return this;
			}

			int min = o.Count;
			if (Count < min)
				min = Count;

			for (int i = 0; i < min; i++) {
				if (o [i])
					this [i] = true;
			}

			return this;
		}
		// <summary>
		//   Performs an `and' operation on the bit vector.  The `new_vector' may have
		//   a different size than the current one.
		// </summary>
		private MyBitVector And (MyBitVector new_vector)
		{
			if (Count == 0)
				return this;

			var o = new_vector.vector != null ? new_vector.vector : new_vector.shared;

			if (o == null) {
				for (int i = new_vector.Count; i < Count; ++i)
					this [i] = false;
				return this;
			}

			if (o.Count == 0) {
				SetAll (false);
				return this;
			}

			if (Count == o.Count) {
				if (vector == null) {
					if (shared == null) {
						shared = new_vector.MakeShared (Count);
						return this;
					}
					initialize_vector ();
				}
				vector.And (o);
				return this;
			}

			int min = o.Count;
			if (Count < min)
				min = Count;

			for (int i = 0; i < min; i++) {
				if (! o [i])
					this [i] = false;
			}

			for (int i = min; i < Count; i++)
				this [i] = false;

			return this;
		}
		public MyBitVector (MyBitVector InheritsFrom, int Count)
		{
			if (InheritsFrom != null)
				shared = InheritsFrom.MakeShared (Count);

			this.Count = Count;
		}
		public void SetStructFieldAssigned (MyBitVector vector, string field_name)
		{
			if (vector[Offset])
				return;

			int field_idx = TypeInfo.GetFieldIndex (field_name);

			if (field_idx == 0)
				return;

			var complex_field = TypeInfo.GetStructField (field_name);
			if (complex_field != null) {
				vector.SetRange (Offset + complex_field.Offset, complex_field.TotalLength);
			} else {
				vector[Offset + field_idx] = true;
			}

			IsEverAssigned = true;

			//
			// Each field must be assigned
			//
			for (int i = Offset + 1; i < TypeInfo.TotalLength + Offset; i++) {
				if (!vector[i])
					return;
			}

			//
			// Set master struct flag to assigned when all tested struct
			// fields have been assigned
			//
			vector[Offset] = true;
		}
		public void SetAssigned (MyBitVector vector)
		{
			if (Length == 1)
				vector[Offset] = true;
			else
				vector.SetRange (Offset, Length);

			IsEverAssigned = true;
		}
		public bool IsStructFieldAssigned (MyBitVector vector, string field_name)
		{
			int field_idx = TypeInfo.GetFieldIndex (field_name);

			if (field_idx == 0)
				return true;

			return vector [Offset + field_idx];
		}
		public bool IsAssigned (MyBitVector vector)
		{
			if (vector == null)
				return true;

			if (vector [Offset])
				return true;

			// Unless this is a struct
			if (!TypeInfo.IsStruct)
				return false;

			//
			// Following case cannot be handled fully by SetStructFieldAssigned
			// because we may encounter following case
			// 
			// struct A { B b }
			// struct B { int value; }
			//
			// setting a.b.value is propagated only to B's vector and not upwards to possible parents
			//
			//
			// Each field must be assigned
			//
			for (int i = Offset + 1; i <= TypeInfo.Length + Offset; i++) {
				if (!vector[i])
					return false;
			}

			// Ok, now check all fields which are structs.
			for (int i = 0; i < sub_info.Length; i++) {
				VariableInfo sinfo = sub_info[i];
				if (sinfo == null)
					continue;

				if (!sinfo.IsAssigned (vector))
					return false;
			}
			
			vector [Offset] = true;
			return true;
		}