Перем РасширениеФайлаМодуля;
Перем БылоПрерывание;

Функция СохраняемаяНастройкаФормы(выхНаименование, выхИменаСвойств) Экспорт 
	выхИменаСвойств = "Форма.ИскатьВходящие, Форма.ИскатьИсходящие, Форма.ФильтрПодсистем";
	Возврат Неопределено;
КонецФункции

Процедура ЗагрузитьНастройкуВФорме(НастройкаФормы, ДопПараметры) Экспорт 
	
	ирКлиент.ЗагрузитьНастройкуФормыЛкс(ЭтаФорма, НастройкаФормы); 
	
КонецПроцедуры

Процедура ПриОткрытии()
	ирКлиент.Форма_ПриОткрытииЛкс(ЭтаФорма,,, Новый Структура("ПриОткрытии"));
	//ирКлиент.ДопСвойстваЭлементаФормыЛкс(ЭтаФорма, ЭлементыФормы.ДеревоВызовов).МенеджерПоиска = ирКлиент.СоздатьМенеджерПоискаВТабличномПолеЛкс(Новый Структура("Текст")); // Для отключения раскраски
	ЭтаФорма.ДатаОбновленияКэша = ирОбщий.ДатаОбновленияКэшаМодулейЛкс();
	ДеревоВызовов.Строки.Очистить();
	ПеренестиВКорень(ПараметрСтрокаМетода);
	ТаблицаТипов = ВычислитьТипЗначенияВыражения(мКонтекст);
	Если ТаблицаТипов.Количество() Тогда
		СтрокаОписания = ТаблицаТипов[0].СтрокаОписания; // см. мПлатформа.НоваяТаблицаМетодовМодуля()[0]
		Если Истина
			И ТипЗнч(СтрокаОписания) = Тип("СтрокаТаблицыЗначений")
			И СтрокаОписания.Владелец().Колонки.Найти("ТелоБезВозвратов") <> Неопределено
		Тогда
			ТекущийВызываемыйМетод = ДеревоВызовов.Строки[0].Строки.Найти(СтрокаОписания.Имя, "Метод");
			Если ТекущийВызываемыйМетод <> Неопределено Тогда
				ЭлементыФормы.ДеревоВызовов.ТекущаяСтрока = ТекущийВызываемыйМетод;
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
КонецПроцедуры

//.
// Параметры:
//    СтрокаМетода - СтрокаТаблицыЗначений - 
Процедура ПеренестиВКорень(Знач СтрокаМетода) Экспорт
	ирОбщий.ОбновитьТекстПослеМаркераЛкс(ЭтаФорма.Заголовок,, СтрокаМетода.Имя, ": "); 
	ДеревоВызовов.Строки.Очистить();
	СтрокаКорня = ДеревоВызовов.Строки.Добавить();
	СтрокаКорня.Метод = СтрокаМетода.Имя;
	СтрокаКорня.Модуль = СтрокаМетода.ИмяМодуля;
	//СтрокаКорня.Позиция = СтрокаМетода.ПозицияОпределения;
	СтрокаКорня.Строки.Добавить();
	ЭлементыФормы.ДеревоВызовов.ТекущаяСтрока = ДеревоВызовов.Строки[0];  
	ОбновитьДанные();
КонецПроцедуры

Процедура ОбновитьДанные() Экспорт
	ЭлементыФормы.ДеревоВызовов.Развернуть(ЭлементыФормы.ДеревоВызовов.ТекущаяСтрока); 
КонецПроцедуры

Процедура ПриЗакрытии()  
	
	ирКлиент.Форма_ПриЗакрытииЛкс(ЭтаФорма);
	
КонецПроцедуры

Функция ТекстФайлаСтроки(Знач ВыбраннаяСтрока = Неопределено)
	
	Если ВыбраннаяСтрока = Неопределено Тогда
		ВыбраннаяСтрока = ЭлементыФормы.ДеревоВызовов.ТекущаяСтрока;
	КонецЕсли;
	ФайлМодуля = мПлатформа.ФайлМодуляИзИмениМодуля(ВыбраннаяСтрока.Модуль);
	ТекстовыйДокумент = Новый ТекстовыйДокумент;
	ТекстовыйДокумент.Прочитать(ФайлМодуля.ПолноеИмя);
	ТекстФайла = ТекстовыйДокумент.ПолучитьТекст();
	Возврат ТекстФайла;

КонецФункции

Процедура ВнешнееСобытие(Источник, Событие, Данные) Экспорт
	
	ирКлиент.Форма_ВнешнееСобытиеЛкс(ЭтаФорма, Источник, Событие, Данные);

КонецПроцедуры

Процедура ТабличноеПолеПриПолученииДанных(Элемент, ОформленияСтрок) Экспорт 
	
	ирКлиент.ТабличноеПолеПриПолученииДанныхЛкс(ЭтаФорма, Элемент, ОформленияСтрок);

КонецПроцедуры

Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник) Экспорт
	
	ирКлиент.Форма_ОбработкаОповещенияЛкс(ЭтаФорма, ИмяСобытия, Параметр, Источник); 

КонецПроцедуры

Процедура КлсКомандаНажатие(Кнопка) Экспорт 
	
	ирКлиент.УниверсальнаяКомандаФормыЛкс(ЭтаФорма, Кнопка);
	
КонецПроцедуры

Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
	Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс(Отказ,, Истина) Тогда
		Возврат;
	КонецЕсли; 
	// Отключил, т.к. важна уникальность окна
	//ЭтаФорма.ОбработкаОбъект = КопияКомпоненты();
	//ПроверитьИнициировать();
КонецПроцедуры

Процедура НайтиВходящие(Знач СтрокаРодителя)
	
	ИмяМодуляПсевдокодаПлатформы = мПлатформа.ИмяМодуляПсевдокодаПлатформы();
	ВходящиеВызовыМетода = ВызовыСлова.ВыгрузитьКолонки();
	ВходящиеВызовыМетода.Колонки.ВызывающийМетод.Имя = "Метод";
	Если Не ПустаяСтрока(СтрокаРодителя.Модуль) Тогда
		ИмяРодногоМодуляБезКонца = ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(ирОбщий.ТекстМеждуМаркерамиЛкс(СтрокаРодителя.Модуль, "[", "]"));
		АнализаторМодуляРодителя = АнализаторМодуля(СтрокаРодителя);
		СтрокаМетодаРодителя = АнализаторМодуляРодителя.мМодульМетаданных.Методы.Найти(НРег(СтрокаРодителя.Метод), "НИмя");
		ФайлыМодулей = Новый Массив; // Массив из Файл
		ПоискВДинамическомМодуле = Истина
			И АнализаторМодуляРодителя.мМодульМетаданных <> Неопределено
			И АнализаторМодуляРодителя.мМодульМетаданных.Имя = мПлатформа.ИмяДинамическогоМодуля()
			И СтрокаРодителя.Модуль = АнализаторМодуляРодителя.мМодульМетаданных.Имя;
		Если ПоискВДинамическомМодуле Тогда
			ФайлыМодулей.Добавить(Неопределено);
		КонецЕсли;
		Маска = "";
		Если ТолькоЛокальные Тогда
			Маска = ИмяРодногоМодуляБезКонца + ".";
		КонецЕсли;
		ирОбщий.ДополнитьМассивЛкс(ФайлыМодулей, НайтиФайлы(мПлатформа.ПапкаКэшаМодулей.ПолноеИмя, Маска + "*." + РасширениеФайлаМодуля, Истина)); 
		мПлатформа.ИнициацияОписанияМетодовИСвойств();
		Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ФайлыМодулей.Количество());
		РегВыражениеКэш = Неопределено;
		Если ТолькоЛокальные Тогда
			НачальныйСчетчик = 2;
		Иначе
			НачальныйСчетчик = 1;
		КонецЕсли;
		ШаблонПрямогоВызова = ШаблонПрямогоВызоваСлова(СтрокаРодителя.Метод);
		Если ФильтрПодсистем.Количество() > 0 Тогда
			ОбъектыВыбранныхПодсистем = ирОбщий.ОбъектыПодсистемЛкс(ФильтрПодсистем);
		КонецЕсли;
		ОбъектМД = Неопределено;
		ПриоритетныеФайлы = Новый Массив;    
		РазделительПутиКФайлу = ирОбщий.РазделительПутиКФайлуЛкс();
		Для Каждого Файл Из ФайлыМодулей Цикл
			Если Ложь
				Или Файл = Неопределено
				Или ирОбщий.СтрНайтиЛкс(Файл.ПолноеИмя, РазделительПутиКФайлу + ИмяРодногоМодуляБезКонца + ".",,,, Ложь) > 0 
			Тогда
				ПриоритетныеФайлы.Добавить(Файл);
			КонецЕсли;
		КонецЦикла;
		Для Каждого Файл Из ПриоритетныеФайлы Цикл
			ФайлыМодулей.Удалить(ФайлыМодулей.Найти(Файл));
			ФайлыМодулей.Вставить(0, Файл);
		КонецЦикла;
		ФайлыМодулей = ПриоритетныеФайлы; // Отсекаем внешние ДеревоВызовов
		Для Каждого Файл Из ФайлыМодулей Цикл
			#Если Сервер И Не Сервер Тогда
				Файл = Новый Файл;
			#КонецЕсли
			Если Файл = Неопределено Тогда
				ПолноеИмяФайла = "";
				ИмяМодуля = мПлатформа.ИмяДинамическогоМодуля();
				ТекстовыйДокумент = ПолеТекста;
			Иначе
				ПолноеИмяФайла = Файл.ПолноеИмя;
				ИмяМодуля = СтрЗаменить(ирОбщий.ПоследнийФрагментЛкс(Файл.ПолноеИмя, мПлатформа.ПапкаКэшаМодулей.ПолноеИмя + "\"), "\", " ");
				ИмяМодуля = ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(ИмяМодуля);
				ТекстовыйДокумент = Неопределено;
			КонецЕсли;
			ирОбщий.ОбработатьИндикаторЛкс(Индикатор,, ИмяМодуля);
			Если ТекстовыйДокумент = Неопределено Тогда
				Если ФильтрПодсистем.Количество() > 0 Тогда
					ОбъектМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(ирОбщий.ПервыеФрагментыЛкс(Файл.ИмяБезРасширения));
					Если ОбъектМД <> Неопределено Тогда
						Если ОбъектыВыбранныхПодсистем[ОбъектМД] = Неопределено тогда
							Продолжить;
						КонецЕсли;
					КонецЕсли;
				КонецЕсли;
				ТекстовыйДокумент = Новый ТекстовыйДокумент;
				ТекстовыйДокумент.Прочитать(ПолноеИмяФайла);
			КонецЕсли;
			ТекстМодуля = ТекстовыйДокумент.ПолучитьТекст();
			Для ЭтапВнутренний = НачальныйСчетчик По 2 Цикл
				Если ЭтапВнутренний = 1 Тогда 
					НайденныеВызовы = мПлатформа.НепрямыеВызовыСловаВМодуле(ИмяМодуля, ТекстовыйДокумент, Файл, ЭтотОбъект, СтрокаРодителя.Метод, Истина);
				ИначеЕсли ЭтапВнутренний = 2 Тогда 
					Если Ложь
						Или (Истина
							//И ИскатьНепрямые 
							И Не ЗначениеЗаполнено(ИмяРодногоМодуляБезКонца))
						Или ирОбщий.СтрНайтиЛкс("." + ИмяМодуля + ".", "." + ИмяРодногоМодуляБезКонца + ".",,,, Ложь) > 0 // TODO переделать на анализ основного объекта формы
					Тогда
						ВхожденияВызова = ирОбщий.НайтиРегВыражениеЛкс(ТекстМодуля, ШаблонПрямогоВызова,,,,,, Истина, РегВыражениеКэш,, ВхожденияВызова); // Без групп для ускорения
						НайденныеВызовы = ВхожденияВызова;
					Иначе
						Продолжить;
					КонецЕсли;
				КонецЕсли; 
				//
				//Если ЭтапВнутренний = 1 Тогда
				//	Продолжить;
				//КонецЕсли;
				//		ШаблонВнешнегоВызова = шПредИмяПрямое+"(?:"+шИмяСТочками+"\.)?("+ШаблонИскатьСлово+")\s*\((?:(?:"+шВыражениеПрограммы+")?"+шРазделитель+"*(?=[,\)])|,)*\)";
				//	ШаблонВнешнегоВызова = ШаблонВнешнегоВызова + "|" + ШаблонЛитерала;
				//ВхожденияВызова = ирОбщий.НайтиРегВыражениеЛкс(ТекстМодуля, ШаблонВнешнегоВызова,,,,,, Истина, РегВыражениеКэш,, ВхожденияВызова); // Без групп для ускорения
				//НайденныеВызовы = ВхожденияВызова;
				Для Каждого ВхождениеВызова Из НайденныеВызовы Цикл
					Если Истина
						И СтрокаРодителя <> Неопределено
						И СтрокаМетодаРодителя <> Неопределено
						И СтрокаРодителя.Модуль = ИмяМодуля
						И ВхождениеВызова.ПозицияВхождения > СтрокаМетодаРодителя.ПозицияОпределения
						И ВхождениеВызова.ПозицияВхождения < СтрокаМетодаРодителя.ПозицияТела
					Тогда
						Продолжить;
					КонецЕсли;
					Попытка
						ТекстВхождения = ВхождениеВызова.ТекстВхождения;
					Исключение
						ТекстВхождения = Сред(ТекстМодуля, ВхождениеВызова.ПозицияВхождения + 1, ВхождениеВызова.ДлинаВхождения);
					КонецПопытки;
					Если ВхождениеВызова.ПозицияВхождения > 1 Тогда
						ТекстВхождения = Сред(ТекстВхождения, 2);
					КонецЕсли;
					СтрокаВызова = ВходящиеВызовыМетода.Добавить();
					СтрокаВызова.Модуль = ИмяМодуля; 
					СтрокаВызова.Текст = СокрЛ(ТекстВхождения);
					СтрокаВызова.Позиция = ВхождениеВызова.ПозицияВхождения + 1;
					СтрокаВызова.ДлинаВхождения = ВхождениеВызова.ДлинаВхождения - 1;  
					СтрокаВызова.Позиция = СтрокаВызова.Позиция + 1;
					УточнитьСтрокуРезультата(СтрокаВызова);
				КонецЦикла;
			КонецЦикла;
		КонецЦикла;
		ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
		Если мМодульМетаданных.СтруктураТипа <> Неопределено Тогда
			Если ирОбщий.ЛиИмяТипаФормыЛкс(мМодульМетаданных.СтруктураТипа.ИмяОбщегоТипа, Истина) Тогда
				ВсеОбработчикиСобытий = ирОбщий.ВсеОбработчикиСобытийФормаЛкс(мМодульМетаданных.СтруктураТипа.Метаданные);
				НайденныеОбработчики = ВсеОбработчикиСобытий.НайтиСтроки(Новый Структура("НОбработчик", НРег(СтрокаРодителя.Метод)));
				Для Каждого НайденныеЭлемент Из НайденныеОбработчики Цикл
					СтрокаВызова = ВходящиеВызовыМетода.Добавить();
					СтрокаВызова.Модуль = мМодульМетаданных.Имя;
					СтрокаВызова.Метод = "<Событие." + НайденныеЭлемент.Имя + "." + НайденныеЭлемент.Событие + ">";
					СтрокаВызова.Текст = "Обработчик";
				КонецЦикла;
			КонецЕсли;
			Если ЛиИмяМодуляСПрямымиСобытиям() Тогда
				СобытияМодуля = ирКэш.СобытияПоИмениОбщегоТипаЛкс(мМодульМетаданных.СтруктураТипа.ИмяОбщегоТипа);
				СтрокаСобытия = ирОбщий.НайтиЭлементКоллекцииЛкс(СобытияМодуля, "НСлово", НРег(СтрокаРодителя.Метод));
				Если СтрокаСобытия <> Неопределено Тогда 
					СтрокаВызова = ВходящиеВызовыМетода.Добавить();
					СтрокаВызова.Модуль = мМодульМетаданных.Имя;
					СтрокаВызова.Метод = "<Событие." + СтрокаРодителя.Метод + ">";
					СтрокаВызова.Текст = "Обработчик";
				КонецЕсли;
			КонецЕсли;
			Если Истина
				И ирОбщий.СтрНачинаетсяСЛкс(мМодульМетаданных.Имя, "ОбщийМодуль.")
				И ТипЗнч(мМодульМетаданных.СтруктураТипа.Метаданные) = Тип("ОбъектМетаданных")
			Тогда 
				ОбъектМД = мМодульМетаданных.СтруктураТипа.Метаданные; // ОбъектМетаданныхОбщийМодуль
				ИмяОбщегоМодуля = ОбъектМД.Имя; 
				ПолноеИмяМетода = ИмяОбщегоМодуля + "." + СтрокаРодителя.Метод;
				Для Каждого ОбъектМД Из Метаданные.ПодпискиНаСобытия Цикл
					Если ирОбщий.СтрокиРавныЛкс(ОбъектМД.Обработчик, ПолноеИмяМетода) Тогда 
						// Для СправочникМенеджер будет пустой набор типов https://www.hostedredmine.com/issues/989526
						СтрокаВызова = ВходящиеВызовыМетода.Добавить();
						//СтрокаВызова.Модуль = мПлатформа.ИмяМодуляПсевдокодаПлатформы();
						СтрокаВызова.Метод = "<" + ОбъектМД.ПолноеИмя() + "." + ОбъектМД.Событие + ">";
						СтрокаВызова.Текст = "Обработчик";
					КонецЕсли;
				КонецЦикла;
				Для Каждого ОбъектМД Из Метаданные.РегламентныеЗадания Цикл
					Если ирОбщий.СтрокиРавныЛкс(ОбъектМД.ИмяМетода, ПолноеИмяМетода) Тогда 
						СтрокаВызова = ВходящиеВызовыМетода.Добавить();
						//СтрокаВызова.Модуль = мПлатформа.ИмяМодуляПсевдокодаПлатформы();
						СтрокаВызова.Метод = "<" + ОбъектМД.ПолноеИмя() + ".Обработчик>";
						СтрокаВызова.Текст = "Обработчик";
					КонецЕсли;
				КонецЦикла;
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	Если Лев(СтрокаРодителя.Метод, 1) = "<" Тогда
		// Поиск в псевдокоде платформы
		Фрагменты = ирОбщий.СтрРазделитьЛкс(ирОбщий.ТекстБезКрайнихСимволовЛкс(СтрокаРодителя.Метод));
		ИмяСобытия = Фрагменты[Фрагменты.ВГраница()];
		ИскомаяСтрока = "//=== " + ИмяСобытия + " ";
		Если ирОбщий.СтрКончаетсяНаЛкс(СтрокаРодителя.Модуль, ".Форма.Модуль") Тогда
			ИскомаяСтрока = ИскомаяСтрока + "- Форма";
		Иначе
			ИскомаяСтрока = ИскомаяСтрока + "- Объект";
		КонецЕсли;
		ТекстовыйДокумент = Новый ТекстовыйДокумент;
		ТекстовыйДокумент.Прочитать(мПлатформа.ИмяФайлаМодуляИзИмениМодуля(ИмяМодуляПсевдокодаПлатформы));
		Вхождения = ирОбщий.НайтиРегВыражениеЛкс(ТекстовыйДокумент.ПолучитьТекст(), ИскомаяСтрока);
		Для Каждого ВхождениеВызова Из Вхождения Цикл
			СтрокаВызова = ВходящиеВызовыМетода.Добавить();
			СтрокаВызова.Модуль = ИмяМодуляПсевдокодаПлатформы; 
			СтрокаВызова.Текст = СокрЛ(ВхождениеВызова.ТекстВхождения);
			СтрокаВызова.Позиция = ВхождениеВызова.ПозицияВхождения + 1;
			СтрокаВызова.ДлинаВхождения = ВхождениеВызова.ДлинаВхождения - 1;  
			СтрокаВызова.Позиция = СтрокаВызова.Позиция + 1;
			УточнитьСтрокуРезультата(СтрокаВызова);
		КонецЦикла;
	КонецЕсли;
	ЭтаФорма.ТекущийЭлемент = ЭлементыФормы.ДеревоВызовов;
	СвернутыеВызовы = ВходящиеВызовыМетода.Скопировать();
	СвернутыеВызовы.Свернуть("Модуль, Метод");
	СвернутыеВызовы.Колонки.Добавить("Места");
	СвернутыеВызовы.Колонки.Добавить("ЧислоВызовов");
	СвернутыеВызовы.Колонки.Добавить("БесконтекстныйСерверный");
	СвернутыеВызовы.Колонки.Добавить("КонтекстныйСерверный");
	Для Каждого СтрокаПары Из СвернутыеВызовы Цикл
		Отбор = Новый Структура;
		Отбор.Вставить("Модуль", СтрокаПары.Модуль);
		Отбор.Вставить("Метод", СтрокаПары.Метод);
		ИменаКолонок = ирОбщий.СтрСоединитьЛкс(ВызовыТекущегоМетода.Колонки,,,,, "Имя");
		СтрокаПары.Места = ВходящиеВызовыМетода.Скопировать(Отбор, ИменаКолонок);
		СтрокаПары.ЧислоВызовов = СтрокаПары.Места.Количество();
		СтрокаМетода = СтрокаМетодаИзСтрокиДерева(СтрокаПары);
		СтрокаПары.БесконтекстныйСерверный = Истина
			И СтрокаМетода <> Неопределено
			И СтрокаМетода.Сервер 
			И СтрокаМетода.БезКонтекста 
			И Не СтрокаМетода.Клиент
			И СтрокаМетодаРодителя <> Неопределено
			И Не СтрокаМетодаРодителя.Сервер 
			И СтрокаМетодаРодителя.Клиент;
		СтрокаПары.КонтекстныйСерверный = Истина
			И СтрокаМетода <> Неопределено
			И СтрокаМетода.Сервер 
			И Не СтрокаМетода.БезКонтекста 
			И Не СтрокаМетода.Клиент 
			И СтрокаМетодаРодителя <> Неопределено
			И Не СтрокаМетодаРодителя.Сервер 
			И СтрокаМетодаРодителя.Клиент;
	КонецЦикла;
	ирОбщий.ЗагрузитьВСтрокиДереваЗначенийЛкс(СвернутыеВызовы, СтрокаРодителя,,,, Истина);
	Для Каждого СтрокаДерева Из СтрокаРодителя.Строки Цикл
		Родитель = СтрокаРодителя;
		Пока Родитель <> Неопределено Цикл
			Если СтрокаДерева.Метод = Родитель.Метод Тогда
				СтрокаДерева.Строки.Очистить();
				Прервать;
			КонецЕсли;
			Родитель = Родитель.Родитель;
		КонецЦикла;
	КонецЦикла; 
	СтрокаРодителя.ВызывающихМетодов = СвернутыеВызовы.Количество();
	
КонецПроцедуры

Процедура НайтиИсходящие(Знач СтрокаРодителя)
	
	Если ПустаяСтрока(СтрокаРодителя.Модуль) Тогда
		Возврат;
	КонецЕсли;
	//ИмяРодногоМодуляБезКонца = ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(ирОбщий.ТекстМеждуМаркерамиЛкс(СтрокаРодителя.Модуль, "[", "]"));
	АнализаторМодуляРодителя = АнализаторМодуля(СтрокаРодителя);
	СтрокаМетодаРодителя = АнализаторМодуляРодителя.мМодульМетаданных.Методы.Найти(НРег(СтрокаРодителя.Метод), "НИмя");
	мПлатформа.ИнициацияОписанияМетодовИСвойств();                                      
	ШаблонПрямогоВызова = ШаблонПрямогоВызоваСлова("((?:" + шИмяСТочками + "\.)?" + мПлатформа.шИмя + ")",, Истина);
	Если ФильтрПодсистем.Количество() > 0 Тогда
		ОбъектыВыбранныхПодсистем = ирОбщий.ОбъектыПодсистемЛкс(ФильтрПодсистем);
	КонецЕсли;
	ОбъектМД = Неопределено;
	ВходящиеВызовыМетода = ВызовыСлова.ВыгрузитьКолонки();
	ВходящиеВызовыМетода.Колонки.ВызывающийМетод.Имя = "Метод";
	Вхождения = ирОбщий.НайтиРегВыражениеЛкс(АнализаторМодуляРодителя.ТелоМетода(СтрокаМетодаРодителя), ШаблонПрямогоВызова);
	АнализаторМодуляРодителя.ЗагрузитьМетодМодуля(СтрокаМетодаРодителя);
	ПозицияТела = АнализаторМодуляРодителя.мПозицияТекстаДляПоискаОпределения;
	Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Вхождения.Количество());
	Для Каждого ВхождениеВызова Из Вхождения Цикл
		ирОбщий.ОбработатьИндикаторЛкс(Индикатор); 
		ВызываемыйМетод = ВхождениеВызова.Группы[0];
		АнализаторМодуляРодителя.ЗагрузитьМетодМодуляПоПозиции(ПозицияТела + ВхождениеВызова.ПозицияВхождения);
		ТаблицаТипов = АнализаторМодуляРодителя.ВычислитьТипЗначенияВыражения(ВызываемыйМетод + "(",,,,,,,,,,,,, ИмяФиктивногоСвойства());
		Если ТаблицаТипов.Количество() > 0 Тогда
			СтрокаМетода = ТаблицаТипов[0].СтрокаОписания; // см. мПлатформа.НоваяТаблицаМетодовМодуля()[0]
			Если Ложь
				Или ТипЗнч(СтрокаМетода) <> Тип("СтрокаТаблицыЗначений") 
				Или СтрокаМетода.Владелец().Колонки.Найти("ИмяМодуля") = Неопределено
			Тогда
				Продолжить;
			КонецЕсли;
		Иначе
			Продолжить;
		КонецЕсли;
		ИмяМодуля = СтрокаМетода.ИмяМодуля;
		Если Истина
			И СтрокаРодителя <> Неопределено
			И СтрокаМетодаРодителя <> Неопределено
			И СтрокаРодителя.Модуль = ИмяМодуля
			И ВхождениеВызова.ПозицияВхождения > СтрокаМетодаРодителя.ПозицияОпределения
			И ВхождениеВызова.ПозицияВхождения < СтрокаМетодаРодителя.ПозицияТела
		Тогда
			Продолжить;
		КонецЕсли;
		ТекстВхождения = ВхождениеВызова.ТекстВхождения;
		Если ВхождениеВызова.ПозицияВхождения > 1 Тогда
			ТекстВхождения = Сред(ТекстВхождения, 2);
		КонецЕсли;
		СтрокаВызова = ВходящиеВызовыМетода.Добавить();
		СтрокаВызова.Модуль = ИмяМодуля;  
		//СтрокаВызова.Текст = СокрЛ(ТекстВхождения);
		СтрокаВызова.Текст = ТекстВхождения;
		СтрокаВызова.Позиция = ПозицияТела + ВхождениеВызова.ПозицияВхождения + 1;
		СтрокаВызова.ДлинаВхождения = ВхождениеВызова.ДлинаВхождения - 1;  
		СтрокаВызова.Позиция = СтрокаВызова.Позиция + 1;
		//УточнитьСтрокуРезультата(СтрокаВызова);
		СтрокаВызова.Метод = СтрокаМетода.Имя;
	КонецЦикла;
	ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
	ЭтаФорма.ТекущийЭлемент = ЭлементыФормы.ДеревоВызовов;
	СвернутыеВызовы = ВходящиеВызовыМетода.Скопировать();
	СвернутыеВызовы.Свернуть("Модуль, Метод");
	СвернутыеВызовы.Колонки.Добавить("Места");
	СвернутыеВызовы.Колонки.Добавить("ЧислоВызовов");
	СвернутыеВызовы.Колонки.Добавить("БесконтекстныйСерверный");
	СвернутыеВызовы.Колонки.Добавить("КонтекстныйСерверный");
	СвернутыеВызовы.Колонки.Добавить("Внешний");
	Для Каждого СтрокаПары Из СвернутыеВызовы Цикл
		Отбор = Новый Структура;
		Отбор.Вставить("Модуль", СтрокаПары.Модуль);
		Отбор.Вставить("Метод", СтрокаПары.Метод);
		ИменаКолонок = ирОбщий.СтрСоединитьЛкс(ВызовыТекущегоМетода.Колонки,,,,, "Имя");
		СтрокаПары.Места = ВходящиеВызовыМетода.Скопировать(Отбор, ИменаКолонок);
		СтрокаПары.ЧислоВызовов = СтрокаПары.Места.Количество();
		АнализаторМодуля = АнализаторМодуля(СтрокаПары);
		Если Не ЗначениеЗаполнено(СтрокаПары.Метод) Тогда
			Продолжить;
		КонецЕсли;
		СтрокаМетода = СтрокаМетодаИзСтрокиДерева(СтрокаПары);
		СтрокаПары.Внешний = СтрокаМетода.ИмяМодуля <> СтрокаМетодаРодителя.ИмяМодуля;
		СтрокаПары.БесконтекстныйСерверный = Истина
			И СтрокаМетода <> Неопределено
			И СтрокаМетода.Сервер 
			И СтрокаМетода.БезКонтекста  
			И Не СтрокаМетода.Клиент 
			И Не СтрокаМетодаРодителя.Сервер 
			И СтрокаМетодаРодителя.Клиент;
		СтрокаПары.КонтекстныйСерверный = Истина
			И СтрокаМетода <> Неопределено
			И СтрокаМетода.Сервер 
			И Не СтрокаМетода.БезКонтекста 
			И Не СтрокаМетода.Клиент 
			И Не СтрокаМетодаРодителя.Сервер 
			И СтрокаМетодаРодителя.Клиент;
	КонецЦикла;
	ирОбщий.ЗагрузитьВСтрокиДереваЗначенийЛкс(СвернутыеВызовы, СтрокаРодителя,, Новый Структура("Выход", Истина),, Истина);
	Для Каждого СтрокаДерева Из СтрокаРодителя.Строки Цикл
		Родитель = СтрокаРодителя;
		Пока Родитель <> Неопределено Цикл
			Если СтрокаДерева.Метод = Родитель.Метод Тогда
				СтрокаДерева.Строки.Очистить();
				Прервать;
			КонецЕсли;
			Родитель = Родитель.Родитель;
		КонецЦикла;
	КонецЦикла; 
	СтрокаРодителя.ВызываемыхМетодов = СвернутыеВызовы.Количество();
	
КонецПроцедуры

Процедура ВызовыПриАктивизацииСтроки(Элемент)
	ЭтаФорма.ВызовыТекущегоМетода = Элемент.ТекущаяСтрока.Места;
КонецПроцедуры

Процедура УточнитьСтрокуРезультата(Знач ТекущаяСтрока, Знач Групповое = Истина) Экспорт
	СтрокаДерева = ЭлементыФормы.ДеревоВызовов.ТекущаяСтрока;
	Если СтрокаДерева.Выход Тогда
		ИмяМодуля = СтрокаДерева.Родитель.Модуль;
	Иначе
		ИмяМодуля = ТекущаяСтрока.Модуль;
	КонецЕсли;
	Если ИмяМодуля = мПлатформа.ИмяДинамическогоМодуля() Тогда
		ЗагрузитьМетодМодуляПоПозиции(ТекущаяСтрока.Позиция);
		ТекущаяСтрока.НомерСтрокиМодуля = НомерСтрокиИзПозиции(ТекущаяСтрока.Позиция);
		Если мМетодМодуля <> Неопределено Тогда
			ТекущаяСтрока.Метод = мМетодМодуля.Имя;
		Иначе
			ТекущаяСтрока.Метод = мПлатформа.ИмяМетодаИнициация();
		КонецЕсли;
		//ТекущаяСтрока.Текст = ПолеТекста.ПолучитьСтроку(ТекущаяСтрока.НомерСтрокиМодуля);
	ИначеЕсли ирОбщий.СтрНачинаетсяСЛкс(СтрокаДерева.Метод, "<") Тогда
		Если ПустаяСтрока(ИмяМодуля) Тогда
			ТекущаяСтрока.Ссылка = ирОбщий.ТекстБезКрайнихСимволовЛкс(СтрокаДерева.Метод);
		ИначеЕсли ирОбщий.СтрКончаетсяНаЛкс(ИмяМодуля, ".Форма.Модуль") Тогда
			ТекущаяСтрока.Ссылка = СтрЗаменить(ИмяМодуля, ".Форма.Модуль", "");
			ТекущаяСтрока.Ссылка = ТекущаяСтрока.Ссылка + "." + СтрокаДерева.Метод;
		КонецЕсли;
	Иначе
		Если Не Групповое Тогда
			ПолеФрагмента = ЭлементыФормы.ПолеТекстаВхождения;
		КонецЕсли;
		ирКлиент.РазобратьПозициюМодуляВСтрокеТаблицыЛкс(ТекущаяСтрока, ИмяМодуля, ПолеФрагмента,,,,, Истина, "Метод");
	КонецЕсли;
КонецПроцедуры

Процедура ВызовыПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки) Экспорт
	Если ДанныеСтроки.Родитель <> Неопределено Тогда
		Если ДанныеСтроки.Выход Тогда
			Картинка = ирКэш.КартинкаПоИмениЛкс("ирВходящий");
		Иначе
			Картинка = ирКэш.КартинкаПоИмениЛкс("ирВыходящий");
		КонецЕсли;
		ОформлениеСтроки.Ячейки.Выход.ОтображатьТекст = Ложь;
		ОформлениеСтроки.Ячейки.Выход.УстановитьКартинку(Картинка);
	КонецЕсли;
	ирКлиент.ТабличноеПолеПриВыводеСтрокиЛкс(ЭтаФорма, Элемент, ОформлениеСтроки, ДанныеСтроки);
КонецПроцедуры

Процедура ДействияФормыПерейтиКОпределению(Кнопка = Неопределено)
	ТекущаяСтрока = ЭлементыФормы.ДеревоВызовов.ТекущаяСтрока;
	Если ТекущаяСтрока = Неопределено Тогда
		Возврат;
	КонецЕсли;
	ирКлиент.ПоказатьСсылкуНаСтрокуМодуляЛкс(ТекущаяСтрока.Ссылка);
КонецПроцедуры

Процедура ИскатьСловоНачалоВыбораИзСписка(Элемент, СтандартнаяОбработка = Истина)
	ирОбщий.ПолеВводаСИсториейВыбора_ОбновитьСписокЛкс(Элемент, ЭтаФорма);
КонецПроцедуры

Процедура НадписьКэшМодулейНажатие(Элемент)
	ПолучитьФорму("Настройки", ФормаВладелец).Открыть();
КонецПроцедуры

Процедура ДействияФормыНайтиВызовыМетода(Кнопка)
	ВыбраннаяСтрока = ЭлементыФормы.ДеревоВызовов.ТекущаяСтрока;
	Если ВыбраннаяСтрока = Неопределено Тогда
		Возврат;
	КонецЕсли;
	ПолеТекстаВызывающее = АнализаторМодуля(ВыбраннаяСтрока);
	ПолеТекстаВызывающее.ОткрытьПоискВызововСлова(ВыбраннаяСтрока.ВызывающийМетод + "(");
КонецПроцедуры

Процедура ФильтрПодсистем_НачалоВыбора(Элемент, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	ФормаВыбора = ирКэш.Получить().ПолучитьФорму("ВыборПодсистемы", Элемент);
	ФормаВыбора.МножественныйВыбор = Истина;
	ФормаВыбора.НачальноеЗначениеВыбора = ФильтрПодсистем;
	ФормаВыбора.РежимВыбора = Истина;
	ФормаВыбора.Открыть();
	
КонецПроцедуры

Процедура ФильтрПодсистем_ПриИзменении(Элемент)

	ирКлиент.ПолеВводаСИсториейВыбора_ПриИзмененииЛкс(Элемент, ЭтаФорма);
	
КонецПроцедуры

Процедура ФильтрПодсистемОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
	ирКлиент.ФильтрПодсистемОбработкаВыбораЛкс(ЭтаФорма, Элемент, ВыбранноеЗначение, СтандартнаяОбработка);
КонецПроцедуры 

Процедура ФильтрПодсистемНачалоВыбораИзСписка(Элемент, СтандартнаяОбработка)
	
	ирОбщий.ПолеВводаСИсториейВыбора_ОбновитьСписокЛкс(Элемент, ЭтаФорма);

КонецПроцедуры

Процедура ВызовыСловаПередРазворачиванием(Элемент, Строка, Отказ)
	Если Истина   
		И Не БылоПрерывание
		И Строка.Строки.Количество() = 1
		И Строка.Строки[0].Модуль = ""
	Тогда
		//
	Иначе
		Возврат;
	КонецЕсли;
	БылоПрерывание = Истина;
	ПодключитьОбработчикОжидания("ЗавершитьРазвертывание", 0.1, Истина); // Не работает этот способ борьбы с рекурсивным разворачиванием
	Строка.Строки.Очистить();   
	Если Ложь
		Или Не Строка.Выход
		Или ИскатьВходящие И Строка.Родитель = Неопределено
	Тогда
		НайтиВходящие(Строка);
	КонецЕсли;
	Если Ложь
		Или Строка.Выход
		Или ИскатьИсходящие И Строка.Родитель = Неопределено
	Тогда
		НайтиИсходящие(Строка);
	КонецЕсли;  
	Строка.Строки.Сортировать("Выход, Метод, Модуль");
	БылоПрерывание = Ложь;
КонецПроцедуры

Процедура ЗавершитьРазвертывание()
	БылоПрерывание = Ложь;
КонецПроцедуры

Процедура ВызовыТекущегоМетодаПриАктивизацииСтроки(Элемент)
	#Если Сервер И Не Сервер Тогда
		мПлатформа = Обработки.ирПлатформа.Создать();
	#КонецЕсли
	ЭлементыФормы.ПолеТекстаВхождения.УстановитьТекст("");
	ТекущаяСтрока = ЭлементыФормы.ВызовыТекущегоМетода.ТекущаяСтрока;
	Если ТекущаяСтрока = Неопределено Тогда
		Возврат;
	КонецЕсли;
	УточнитьСтрокуРезультата(ТекущаяСтрока, Ложь);
КонецПроцедуры

Процедура ВызовыВыбор(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка)
	
	Если ВыбраннаяСтрока.Выход Тогда
		ирКлиент.ОткрытьМетодМодуляПоОпределениюЛкс(СтрокаМетодаИзСтрокиДерева(ВыбраннаяСтрока));
	Иначе
		ВызовыТекущегоМетодаВыбор();
	КонецЕсли;
	
КонецПроцедуры

Процедура ВызовыТекущегоМетодаВыбор(Элемент = Неопределено, ВыбраннаяСтрока = Неопределено, Колонка = Неопределено, СтандартнаяОбработка = Истина)
	ВыбраннаяСтрока = ЭлементыФормы.ВызовыТекущегоМетода.ТекущаяСтрока;
	Если Ложь
		Или ВыбраннаяСтрока = Неопределено 
		Или ПустаяСтрока(ВыбраннаяСтрока.Ссылка)
	Тогда
		Возврат;
	КонецЕсли;
	Колонка = ЭлементыФормы.ВызовыТекущегоМетода.ТекущаяКолонка;
	Если Истина
		И Колонка = ЭлементыФормы.ВызовыТекущегоМетода.Колонки.Ссылка 
		И ирОбщий.СтруктураСсылкиСтрокиМодуляЛкс(ВыбраннаяСтрока.Ссылка) <> Неопределено
	Тогда 
		ДействияФормыПерейтиКОпределению();
	Иначе
		Если Не ирКлиент.ОткрытьСсылкуСтрокиМодуляЛкс(ВыбраннаяСтрока.Ссылка) Тогда 
			Если ВыбраннаяСтрока.Модуль = мПлатформа.ИмяДинамическогоМодуля() Тогда 
				ФормаВладелец.Активизировать();
				ПолеТекстаЛ = ПолеТекста;
			Иначе
				ПолеТекстаЛ = ирКлиент.ОткрытьПолеТекстаМодуляКонфигурацииЛкс(ВыбраннаяСтрока.Модуль).ПолеТекста;
			КонецЕсли;
			ПолеТекстаЛ.УстановитьГраницыВыделения(ВыбраннаяСтрока.Позиция, ВыбраннаяСтрока.Позиция + ВыбраннаяСтрока.ДлинаВхождения,,, Истина);
		КонецЕсли;
	КонецЕсли;
КонецПроцедуры

Процедура ИсходящиеПриИзменении(Элемент)
	ОбновитьДанные();
КонецПроцедуры

Процедура ВходящиеПриИзменении(Элемент)
	ОбновитьДанные();
КонецПроцедуры

Процедура ДействияФормыПеренестиВКорень(Кнопка)
	СтрокаМетода = СтрокаМетодаИзСтрокиДерева();
	ПеренестиВКорень(СтрокаМетода);
КонецПроцедуры

Функция СтрокаМетодаИзСтрокиДерева(СтрокаДерева = Неопределено) Экспорт
	Если СтрокаДерева = Неопределено Тогда
		СтрокаДерева = ЭлементыФормы.ДеревоВызовов.ТекущаяСтрока;
	КонецЕсли;
	Если Лев(СтрокаДерева.Метод, 1) = "<" Тогда
		Возврат Неопределено;
	КонецЕсли;
	АнализаторМодуля = АнализаторМодуля(СтрокаДерева);
	СтрокаМетода = АнализаторМодуля.мМодульМетаданных.Методы.Найти(НРег(СтрокаДерева.Метод), "НИмя");
	СтрокаМетода.ИмяМодуля = СтрокаДерева.Модуль;
	Возврат СтрокаМетода;
КонецФункции

// TODO перенести в модуль объекта
Функция АнализаторМодуля(Знач СтрокаДерева = Неопределено) Экспорт
	Если СтрокаДерева = Неопределено Тогда
		СтрокаДерева = ЭлементыФормы.ДеревоВызовов.ТекущаяСтрока;
	КонецЕсли;
	Если СтрокаДерева.Модуль = мПлатформа.ИмяДинамическогоМодуля() Тогда
		АнализаторМодуля = ЭтотОбъект;
	Иначе
		АнализаторМодуля = мПлатформа.ПолеТекстаМодуля(СтрокаДерева.Модуль);
	КонецЕсли;
	Возврат АнализаторМодуля;
КонецФункции

ирКлиент.ИнициироватьФормуЛкс(ЭтаФорма, "Обработка.ирКлсПолеТекстаПрограммы.Форма.ДеревоВызовов");
#Если Сервер И Не Сервер Тогда
	ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
	ПараметрСтрокаМетода = мПлатформа.ПараметрыМетодаМодуля()[0];
#КонецЕсли    
РасширениеФайлаМодуля = "txt";  
ДеревоВызовов.Колонки.Добавить("Места", Новый ОписаниеТипов("ТаблицаЗначений")); 
ИскатьВходящие = Истина;
ИскатьИсходящие = Истина;
ТолькоЛокальные = Истина;
БылоПрерывание = Ложь; 
